~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to libsrc/tbl/tct.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
3
 
 
4
  This program is free software; you can redistribute it and/or 
 
5
  modify it under the terms of the GNU General Public License as 
 
6
  published by the Free Software Foundation; either version 2 of 
 
7
  the License, or (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public 
 
15
  License along with this program; if not, write to the Free 
 
16
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
 
17
  MA 02139, USA.
 
18
 
 
19
  Correspondence concerning ESO-MIDAS should be addressed as follows:
 
20
        Internet e-mail: midas@eso.org
 
21
        Postal address: European Southern Observatory
 
22
                        Data Management Division 
 
23
                        Karl-Schwarzschild-Strasse 2
 
24
                        D 85748 Garching bei Muenchen 
 
25
                        GERMANY
 
26
===========================================================================*/
 
27
 
 
28
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
29
.TYPE           Module
 
30
.NAME           tct.c
 
31
.LANGUAGE       C
 
32
.AUTHOR         IPG-ESO Garching
 
33
.CATEGORY       table interface 
 
34
.VERSION  1.0   25-Mar-1987   Definition     J.D. Ponz
 
35
.VERSION  3.0   01-Jul-1990     New Version with Arrays / Elementary IO
 
36
 
 
37
 090406         last modif
 
38
 
 
39
 
 
40
.COMMENTS    
 
41
This module contains the routines to handle tables as a whole. 
 
42
Table initialization and open table functions return the
 
43
table identification tid, used by other table routines.
 
44
 
 
45
Tables are physically stored on disk in two different formats:
 
46
by records, corresponding to the natural way of storing sequentially
 
47
the rows, and transposed, where all the values of a single variable
 
48
-- column -- are stored together. 
 
49
It is the responsibility of the user to decide the physical format
 
50
when initializing the table file.
 
51
 
 
52
The functions provided by this module are:
 
53
 
 
54
Create or Initialize a table (TCTINI)
 
55
Open an existing table (TCTOPN)
 
56
Map an opened table to virtual memory (TCTMAP)
 
57
Unmap a mapped table (TCTUNM): write modified parts, unmap mapped pieces
 
58
Close a table (TCTCLO).
 
59
 
 
60
Main arguments used by the routines are:
 
61
allcol:  number of words per record allocated physically in the
 
62
            table file.
 
63
allrow:  number of records (rows) allocated physically in the
 
64
            table file.
 
65
mode:    file opening mode. There are several modes to open a table:
 
66
               F_I\_MODE input (TBTOPN), 
 
67
               F_O\_MODE output (TBTINI), 
 
68
               F_IO\_MODE input/output (TBTOPN), 
 
69
               F_X\_MODE scratch (TBTINI), 
 
70
               F_D\_MODE descriptors only (TBTOPN).
 
71
           These symbols are provided in the file 'midas_def.h'
 
72
           in the directory 'MID_INCLUDE'.
 
73
 
 
74
           The access mode may be forced to mapping with the F_MAP_FORCE
 
75
           option, or to elementary i/o mode with the F_EIO_FORCE
 
76
           option. The default is EIO mode for tables larger than
 
77
           TBL_EIO_LIMIT bytes, a configuration parameter
 
78
           which may be changed with TCOSET
 
79
name:    table file name. It is a character string defining the
 
80
           file name of the table as follows: '[path_name]table_name[.ext]',
 
81
           where 'path_name' is the directory path name, defaulted to
 
82
           the working directory, 'table_name' is the name of the file
 
83
           and 'ext' is the file extension, defaulted to 'tbl'.
 
84
storage: physical file format. Defined as F_RECORD if the table
 
85
           is stored by records, or F_TRANS for transposed format.
 
86
           These symbols are provided in the file 'midas_def.h'
 
87
           in the directory 'MID_INCLUDE'.
 
88
tid:     table identifier. It is an integer number provided by the
 
89
           system when the table is created or opened.
 
90
------------------------------------------------------------*/
 
91
 
 
92
#include <fileexts.h>           /* General MIDAS Symbols        */
 
93
 
 
94
#include <tblsys.h>             /* Table System parameters      */
 
95
#include <tbldef.h>             /* Symbols used for Tables      */
 
96
#include <tblerr.h>             /* List of Table Errors         */
 
97
 
 
98
#include <macrogen.h>           /* Classical macros             */
 
99
 
 
100
#include <stdlib.h>             /* for malloc, free */
 
101
#include <stdio.h>
 
102
 
 
103
 
 
104
static int dunit=-1;            /* For future use */
 
105
 
 
106
static int eio_limit = TBL_EIO_LIMIT;
 
107
 
 
108
char    *osmmget(), *osmmexp(); /* Memory Allocation Functions  */
 
109
 
 
110
/*
 
111
 
 
112
*/
 
113
        
 
114
/*=======================================================================
 
115
 *              Conversion of NULL values from old to New
 
116
 *=======================================================================*/
 
117
 
 
118
#ifdef __STDC__
 
119
static int convert_nulls(TABLE *tp)
 
120
#else
 
121
static int convert_nulls(tp)
 
122
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
123
.PURPOSE  Change NULL values to -Infinity
 
124
.METHOD   Assume that table is MAPPED.
 
125
.RETURNS  Number of Modified Columns
 
126
------------------------------------------------------------------*/
 
127
        TABLE   *tp;    /* MOD: Table concerned */
 
128
#endif
 
129
{
 
130
        int     i, j, di, o, cols;
 
131
        char    *pv;
 
132
        float   fnull;
 
133
        double  ddnull;
 
134
 
 
135
  TBL_toNULL((TBL_D_R4<<TBL_D_BITS)|1, (char *)&fnull);
 
136
  TBL_toNULL((TBL_D_R8<<TBL_D_BITS)|1, (char *)&ddnull);
 
137
  cols = 0;
 
138
 
 
139
  for (j = 0; j < tp->cols; j++) {
 
140
        if (tp->swise == F_TRANS)
 
141
                o = tp->offset[j] * tp->arows, di = tp->bytes[j];
 
142
        else    o = tp->offset[j],              di = tp->reclen;
 
143
 
 
144
        switch(tp->dtypes[j] >> TBL_D_BITS) {
 
145
          default:              continue;
 
146
          case TBL_D_R4:
 
147
                cols++;
 
148
                for (pv = tp->addres + o, i = tp->arows; --i >= 0; pv += di) {
 
149
                        if (*((float *)pv) > 1.e38)     *(float *)pv = fnull;
 
150
                }
 
151
                break;
 
152
          case TBL_D_R8:
 
153
                cols++;
 
154
                for (pv = tp->addres + o, i = tp->arows; --i >= 0; pv += di) {
 
155
                        if (*((double *)pv) > 1.e38)    *(double *)pv = ddnull;
 
156
                }
 
157
                break;
 
158
        }
 
159
  }
 
160
  return(cols);
 
161
}
 
162
/*
 
163
 
 
164
*/
 
165
 
 
166
int dummyPUT(imno,size)
 
167
 
 
168
int  imno, size;
 
169
 
 
170
{
 
171
int  status;
 
172
 
 
173
char  *fpt;
 
174
 
 
175
struct FCT_STRUCT  *fctpntr;
 
176
 
 
177
 
 
178
 
 
179
 
 
180
 
 
181
 
 
182
fctpntr = FCT.ENTRIES + imno;
 
183
fctpntr->FILTYP = 22;
 
184
 
 
185
fpt = osmmget((unsigned int) (size * sizeof(float)));   /* already set to 0 */
 
186
status = SCFPUT(imno,1,size,fpt);
 
187
 
 
188
fctpntr->FILTYP = 2;
 
189
osmmfree(fpt);
 
190
 
 
191
return (status);
 
192
}
 
193
/*
 
194
 
 
195
*/
 
196
 
 
197
/*=======================================================================
 
198
 *              Private Routines
 
199
 *=======================================================================*/
 
200
 
 
201
#ifdef __STDC__
 
202
static int TBL_setcols(TABLE *tp)
 
203
#else
 
204
static int TBL_setcols(tp)
 
205
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
206
.PURPOSE        Set up configuration of the arrays with physical columns
 
207
.ALGORITHM      Allocate memory, and compute offset + length, set formats
 
208
.RETURNS        length of 1 record
 
209
------------------------------------------------------------------*/
 
210
TABLE   *tp;    /* MOD: Table concerned */
 
211
#endif
 
212
 
 
213
{
 
214
int     n, len1, icode, ncur, i;
 
215
 
 
216
 
 
217
 
 
218
 
 
219
/* Compute derived quantities           */
 
220
 
 
221
tp->reclen = (tp->acols + 1) * 4;
 
222
tp->wsize = (tp->acols + 1) * tp->arows;
 
223
 
 
224
/* Store correct locations of arrays    */
 
225
 
 
226
n = tp->colitems;
 
227
tp->bytes  = (int *)osmmget(n*2*sizeof(int));
 
228
tp->abytes = tp->bytes  + n;    
 
229
tp->label  = osmmget(n*(2+TBL_FORLEN+TBL_LABLEN));
 
230
tp->format = tp->label + n*(1+TBL_LABLEN);
 
231
 
 
232
/* Compute length + offset of each column */
 
233
 
 
234
ncur = 4;
 
235
for (i=0; i<tp->cols; i++) 
 
236
   {
 
237
   icode = tp->dtypes[i];
 
238
   
 
239
   /*  we don't check this anymore - KB 040121
 
240
 
 
241
   if (icode < 0) 
 
242
      {                         /. Convert OLD definitions to new ones  ./
 
243
      switch (icode)    
 
244
         {  
 
245
         default:
 
246
         case -4:        icode = TBL_D_R4;      break;
 
247
         case -8:        icode = TBL_D_R8;      break;
 
248
         case -11:       icode = TBL_D_I1;      break;
 
249
         case -12:       icode = TBL_D_I2;      break;
 
250
         case -14:       icode = TBL_D_I4;      break;
 
251
         }
 
252
      icode = (icode << TBL_D_BITS) | 1;
 
253
      tp->dtypes[i] = icode;
 
254
      }
 
255
   */
 
256
 
 
257
   len1 = TBL_ElementSize(icode);
 
258
   n = TBL_Items(icode);
 
259
 
 
260
   if (tp->version == 0)        
 
261
      {                         /* BEWARE ! (MP) Old to New implies
 
262
                                   true len of CHAR is multiple of 4 */
 
263
      n = ((3+len1*n)>>2)<<2;     /* n is now Multiple of 4 */
 
264
      n /= len1;   
 
265
      tp->offset[i] = ncur;
 
266
      if (!(icode>>TBL_D_BITS)) tp->dtypes[i] = n; /* MP 070291 */
 
267
      }
 
268
 
 
269
   tp->bytes[i] = len1*n;
 
270
   ncur += tp->bytes[i];
 
271
  }
 
272
 
 
273
 
 
274
/* Zero unused values   */
 
275
 
 
276
for (; i < tp->colitems; i++) 
 
277
   tp->dtypes[i] = tp->offset[i] = tp->bytes[i] = 0;
 
278
        
 
279
 
 
280
/* Formats not loaded   */
 
281
 
 
282
len1 = 1+TBL_FORLEN;
 
283
n = 0;
 
284
for (i=0; i < tp->colitems; i++) 
 
285
   {
 
286
   tp->format[n] = '\0';
 
287
   n += len1;
 
288
   }
 
289
        
 
290
 
 
291
/* Labels not loaded    */
 
292
 
 
293
len1 = 1+TBL_LABLEN;
 
294
n = 0;
 
295
for (i=0; i < tp->colitems; i++)
 
296
   {
 
297
   tp->label[n] = '\0';
 
298
   n += len1;
 
299
   }
 
300
        
 
301
return (ncur);
 
302
}
 
303
/*
 
304
 
 
305
*/
 
306
 
 
307
#ifdef __STDC__
 
308
static int do_map(TABLE *tp, int mode)
 
309
#else
 
310
static int do_map(tp, mode)
 
311
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
312
.PURPOSE Choose the mode for file access (EIO / Mapping / Simulated Mapping)
 
313
.RETURNS status
 
314
------------------------------------------------------------------*/
 
315
        TABLE   *tp;    /* IN: Table to map     */
 
316
        int     mode;   /* IN: Mode for Mapping */
 
317
#endif
 
318
{
 
319
        int     status;
 
320
        int     dummy, i;
 
321
        float   null_float;
 
322
        
 
323
 
 
324
 
 
325
 
 
326
  status = ERR_NORMAL;
 
327
  tp->cbuf = tp->nbuf = 0;
 
328
  tp->tbuf = (TABLE_BUF *)0;
 
329
  tp->sbuf = 0;
 
330
  tp->addres = (char *)0;
 
331
  tp->loaded_map = (unsigned char *)0;
 
332
  tp->vsel       = (unsigned char *)0;
 
333
  tp->vsize      = 0;
 
334
  
 
335
        /* Check, for old versions, of possible bad NULL values.
 
336
           Changing NULL values also implies loding the table,
 
337
           and therefore the F_MAP_FORCE is set.
 
338
           Note that this test is only temporarly required, until
 
339
           no table with old format exists any more...
 
340
        */
 
341
 
 
342
  if (tp->version == 0) {
 
343
        TBL_toNULL((TBL_D_R4<<TBL_D_BITS)|1, (char *)&null_float);
 
344
    /* if (null_float < -1.e38) tp->tflags |= TBL__BADNULLS; */
 
345
        tp->tflags |= TBL__BADNULLS;
 
346
        mode = F_MAP_FORCE|F_IO_MODE;
 
347
 
 
348
  }
 
349
 
 
350
        /* Choose the mode: TBL__MAPPED, or TBL__EIO.
 
351
           If no option, use TBL_EIO if size > TBL_EIO_LIMIT    */
 
352
 
 
353
  if (mode & F_MAP_FORCE)       tp->tflags |= TBL__MAPPED;
 
354
  else if (mode & F_EIO_FORCE)  tp->tflags |= TBL__EIO;
 
355
  if ((tp->tflags& (TBL__MAPPED|TBL__EIO)) == 0) {
 
356
        if (sizeof(int)*tp->acols*tp->arows > eio_limit)
 
357
                tp->tflags |= TBL__EIO;
 
358
  }
 
359
  if (tp->tflags & TBL__MAPPED) {
 
360
        status = SCFMAP(tp->imno, mode&0xf, 1,0,&dummy,&tp->addres);
 
361
        if_not(tp->tflags & TBL__READONLY)      tp->tflags |= TBL__MODIFIED;
 
362
  }
 
363
  else  if (tp->tflags & TBL__EIO) {    /* Elementary Mode. Define Buffers */
 
364
        /* Let's assume at least one buffer per column (in case the table
 
365
           is stored columnwise and accessed recordwise) + Selection + another
 
366
        */
 
367
        tp->nbuf = tp->acols + 2;
 
368
        if (tp->nbuf < TBL_TBUFS)       tp->nbuf = TBL_TBUFS;
 
369
        i = tp->nbuf * sizeof(TABLE_BUF);
 
370
        tp->tbuf = (TABLE_BUF *)osmmget(i);
 
371
        oscfill ((char *)tp->tbuf, i, 0);
 
372
  }
 
373
  else {                        /* BitMap contains size/64k bytes       */
 
374
        i = sizeof(float)*(tp->acols + 1) * tp->arows;
 
375
        tp->addres = osmmget(i);
 
376
        i = (1 + (i|0xffff)) >> 16;
 
377
        tp->loaded_map   = (unsigned char *)osmmget(2*i);
 
378
        tp->modified_map = tp->loaded_map + i;
 
379
        oscfill ((char *)tp->loaded_map, 2*i, 0);
 
380
  }
 
381
  if (status)   TBL_errf(status, "can't map table: %s", tp->phname);
 
382
  return(status);
 
383
}
 
384
 
 
385
/*=======================================================================
 
386
 *              Public Routines
 
387
 *=======================================================================*/
 
388
 
 
389
int TCTCLO(tid)
 
390
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
391
.PURPOSE        Closes table file .
 
392
.ALGORITHM      First Unmap, then release used memory.
 
393
.RETURNS        status
 
394
------------------------------------------------------------------*/
 
395
        int     tid;    /* IN : table id        */
 
396
{
 
397
TABLE   *tp;
 
398
 
 
399
int     status, i;
 
400
 
 
401
char    save_name[100];
 
402
 
 
403
 
 
404
 
 
405
 
 
406
 
 
407
tp = TBL_ptr(tid);
 
408
if ((status = CheckTable(tp))) return(TBL_errs(tid, status,0));
 
409
 
 
410
if (tp->intlFITS == 'F') 
 
411
   {                                    /* SCFCLO may still need FITS data */
 
412
   if ((status = TCTUNMF(tid,0))) return(status);
 
413
 
 
414
   status =  SCFCLO(tp->imno);
 
415
   (void) TCTUNMF(tid,1);               /* now, also free table data memory */
 
416
   goto free_memory;
 
417
   }
 
418
 
 
419
if ((status = TCTUNM(tid))) return(status);
 
420
 
 
421
status = SCFCLO(tp->imno);
 
422
if (status == -99)                      /* we have to convert to FITS */
 
423
   (void) strcpy(save_name,tp->phname);
 
424
 
 
425
 
 
426
/* Free allocated memory of table */
 
427
 
 
428
free_memory:
 
429
if (tp->phname != (char *) 0) osmmfree(tp->phname); 
 
430
if (tp->loaded_map != (unsigned char *) 0)   osmmfree((char *)tp->loaded_map); 
 
431
if (tp->usname != (char *) 0) osmmfree(tp->usname); 
 
432
 
 
433
if (!(tp->tflags&TBL__MAPPED)) 
 
434
   {
 
435
   if (tp->addres != (char *) 0) osmmfree(tp->addres);
 
436
   }
 
437
 
 
438
if (tp->label != (char *) 0) osmmfree(tp->label); 
 
439
  
 
440
if (tp->dtypes != (int *) 0)           osmmfree((char *)tp->dtypes); 
 
441
if (tp->bytes  != (int *) 0)           osmmfree((char *)tp->bytes); 
 
442
if (tp->tbuf   != (TABLE_BUF *) 0)     osmmfree((char *)tp->tbuf); 
 
443
if (tp->vsel   != (unsigned char *) 0) osmmfree((char *)tp->vsel); 
 
444
TBL_kill(tid);
 
445
 
 
446
 
 
447
if (status == -99)                      /* we have to convert to FITS */
 
448
   {
 
449
   char   temp[12], delname[80];
 
450
 
 
451
   delname[0] = '\0';
 
452
   status = TCTOPN(save_name,F_I_MODE,&i); 
 
453
   if (status == 0)
 
454
      {
 
455
      tid = i;
 
456
      status = SCFSAV(tid,2);           /* convert table to FITS */
 
457
      if (status != ERR_NORMAL) return (status);
 
458
 
 
459
      status = SCFCLO(tid);
 
460
      if (status == ERR_NORMAL) 
 
461
         {
 
462
         status = osfrename("midFITS.mt",save_name);
 
463
         if (status != 0)
 
464
            {
 
465
            status = ERR_INPINV;
 
466
            (void) sprintf(temp,"TCTCLO/osfrename: %s ",save_name);
 
467
            MID_ERROR("MID",temp,status,0);
 
468
            return (status);
 
469
            }
 
470
 
 
471
         tp = TBL_ptr(tid);
 
472
         goto free_memory;
 
473
         }
 
474
      }
 
475
   }
 
476
 
 
477
return (status);
 
478
}
 
479
 
 
480
int TCTCRV(name, refer_name, mode)
 
481
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
482
.PURPOSE
 
483
        Create a view (a table with only a Selection Column)
 
484
        taking columns from another (existing!) table.
 
485
.ALGORITHM
 
486
        The view is ONLY CREATED. It must later be opened ...
 
487
.RETURNS
 
488
        Status
 
489
------------------------------------------------------------------*/
 
490
        char    *name;          /* IN : Name of view to create  */
 
491
        char    *refer_name;    /* IN : Name of related table   */
 
492
        int     mode;           /* IN : creation mode (future)  */
 
493
{
 
494
        int     status;
 
495
        int     vid;
 
496
        TABLE   *vp;
 
497
 
 
498
 
 
499
        /* Operations:
 
500
           1- TCTOPN refer_table in read-only mode; check.
 
501
           2- Create file. Set all bits to 1.
 
502
           3- Copy column definitions
 
503
           4- Copy selections ? 
 
504
        */
 
505
 
 
506
 
 
507
 
 
508
                      
 
509
  if ((status = TCTOPN (refer_name, F_I_MODE | F_EIO_FORCE, &vid))) 
 
510
        return (status);
 
511
 
 
512
  vp = TBL_ptr (vid);
 
513
  if (vp->swise & F_B_VIEW) {   
 
514
        TCTCLO (vid);
 
515
        return (TBL_errf(ERR_TBLENT, "can't create view of the view: %s",
 
516
                refer_name));
 
517
  }
 
518
  vp->swise |= F_B_VIEW;
 
519
  vp->vsize = 4 + (vp->rows>>3) ; 
 
520
  vp->vsel  = (unsigned char *)osmmget( vp->vsize );
 
521
  oscfill ((char *)vp->vsel, vp->vsize, ~0);
 
522
 
 
523
  if ((status = SCFCRE (name, D_R4_FORMAT, F_O_MODE, F_TBL_TYPE, 
 
524
        vp->vsize>>2, &vp->vno)))       goto error;
 
525
 
 
526
  status = SCFPUT(vp->vno,1,vp->vsize,(char *)vp->vsel);
 
527
                                        /* Add refer_table as descriptor */
 
528
  status = SCDWRC(vp->vno, TBL_Dview, 1, refer_name, 1, strlen(refer_name), &dunit);
 
529
  if (status)   goto error;
 
530
                                        /* copy descriptors */
 
531
  if ((status = SCDCOP(vp->imno, vp->vno, 1, " ")))
 
532
        goto error;
 
533
                                        /* Rewrite Main Descriptor      */
 
534
  if ((status = SCDWRI(vp->vno, TBL_Dmain, &vp->acols,
 
535
                1,TBL_Dmain_SIZE,&dunit)))      goto error;
 
536
        
 
537
  SCFCLO(vp->vno);
 
538
  error:                                        /* error in SC routines */
 
539
  TCTCLO (vid);
 
540
  if (status)   TBL_errs(vid, status, 0);
 
541
  return ( status );
 
542
}
 
543
/*
 
544
 
 
545
*/
 
546
 
 
547
int TCTUNMF(tid,flag)
 
548
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
549
.PURPOSE        Unmap (Flush) FITS table file in 2 calls
 
550
.ALGORITHM      1st call: write back modified parts 
 
551
                2nd call: release used memory
 
552
.RETURNS        status
 
553
------------------------------------------------------------------*/
 
554
int     tid;    /* IN : table id        */
 
555
int     flag;   /* IN : 0 = do 1st part of TCTUNM
 
556
                        1 = do 2nd part of TCTUNM */
 
557
 
 
558
{
 
559
TABLE   *tp;
 
560
TABLE_BUF *bp;
 
561
 
 
562
int    status, i, newtid;
 
563
 
 
564
 
 
565
 
 
566
 
 
567
tp = TBL_ptr(tid);
 
568
status = ERR_NORMAL;
 
569
 
 
570
if (flag == 0)
 
571
   {
 
572
   if (tp->phname == (char *) 0) return ERR_NORMAL;     /* nothing to do */
 
573
 
 
574
 
 
575
   if (tp->vsize != 0 && tp->usname)
 
576
      {
 
577
      if (tp->tflags & TBL__VREADONLY)
 
578
         ;
 
579
      else
 
580
         {
 
581
         status = SCFOPN(tp->usname,D_R4_FORMAT,F_O_MODE,F_TBL_TYPE, &newtid);
 
582
         status = SCFPUT (newtid, 1, tp->vsize, (char *)tp->vsel);
 
583
         status = SCFCLO(newtid);
 
584
         }
 
585
      }
 
586
 
 
587
 
 
588
   if ((tp->tflags & (TBL__READONLY|TBL__MODIFIED)) == TBL__MODIFIED)
 
589
      {
 
590
      if_not (tp->tflags & TBL__KEEPVERS) 
 
591
             tp->version = TBL_VERSION;
 
592
 
 
593
      /* If ALL is selected, correct number of selected rows       */
 
594
 
 
595
      if ((tp->selected < 0) && (tp->select == '\1'))
 
596
          tp->selected = tp->rows;
 
597
      }
 
598
 
 
599
   if (tp->tflags != TBL__READONLY)     /* if_not (tp->tflags & TBL__MAPPED) */
 
600
      status = TBL_WR (tp);
 
601
   }
 
602
 
 
603
else
 
604
   {
 
605
   if (tp->addres != (char *) 0)
 
606
      {
 
607
      osmmfree(tp->addres);
 
608
      tp->addres = (char *) 0;    /* MP 920909 */
 
609
      }
 
610
 
 
611
   for (i=0; i<tp->nbuf; i++)
 
612
      {
 
613
      bp = tp->tbuf+i;
 
614
      if (bp && bp->buf) osmmfree(bp->buf);
 
615
      }
 
616
   }
 
617
 
 
618
return (status);
 
619
}
 
620
 
 
621
/*
 
622
 
 
623
*/
 
624
int TCTFIX(tid)
 
625
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
626
.PURPOSE        free allocated memory
 
627
.RETURNS        status
 
628
 
 
629
added by KB  980428
 
630
 990624
 
631
------------------------------------------------------------------*/
 
632
int     tid;    /* IN : table id        */
 
633
 
 
634
{
 
635
        TABLE   *tp;
 
636
        int     status;
 
637
 
 
638
 
 
639
 
 
640
 
 
641
  tp = TBL_ptr(tid);
 
642
  if ((status = TCTUNM(tid))) return(status);
 
643
 
 
644
                        /* Free allocated memory        */
 
645
  osmmfree(tp->phname);
 
646
  tp->phname = (char *) 0;
 
647
                                        /* tp->usname is NOT used currently */
 
648
  osmmfree((char *)tp->dtypes);
 
649
  tp->dtypes = (int *) 0;
 
650
 
 
651
  osmmfree((char *)tp->bytes);
 
652
  tp->bytes = (int *) 0;
 
653
 
 
654
  osmmfree(tp->label);
 
655
  tp->label = (char *) 0;
 
656
 
 
657
  if (!(tp->tflags&TBL__MAPPED))
 
658
     {
 
659
     if (tp->addres != (char *) 0)
 
660
        {
 
661
        osmmfree(tp->addres);
 
662
        tp->addres = (char *) 0;
 
663
        }
 
664
     }
 
665
  osmmfree((char *)tp->tbuf);
 
666
  tp->tbuf = (TABLE_BUF *) 0;
 
667
 
 
668
  osmmfree((char *)tp->loaded_map);
 
669
  tp->loaded_map = (unsigned char *) 0;
 
670
 
 
671
  osmmfree((char *)tp->vsel);
 
672
  tp->vsel = (unsigned char *) 0;
 
673
 
 
674
  return (status);
 
675
}
 
676
 
 
677
int TCTUNM(tid)
 
678
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
679
.PURPOSE        Unmap (Flush) table file
 
680
.ALGORITHM      Writes back modified parts and releases used memory.
 
681
.RETURNS        status
 
682
------------------------------------------------------------------*/
 
683
        int     tid;    /* IN : table id        */
 
684
{
 
685
        TABLE   *tp;
 
686
        TABLE_BUF *bp;
 
687
        int     status;
 
688
        int     i,newtid;
 
689
 
 
690
 
 
691
 
 
692
tp = TBL_ptr(tid);
 
693
if ((status = CheckTable(tp)))  return(TBL_errs(tid, status,0));
 
694
 
 
695
if (tp->vsize != 0 && tp->usname)
 
696
   {
 
697
   if (tp->tflags & TBL__VREADONLY)     
 
698
      ;
 
699
   else
 
700
      {
 
701
      status = SCFOPN(tp->usname,D_R4_FORMAT,F_O_MODE,F_TBL_TYPE, &newtid);
 
702
      status = SCFPUT (newtid, 1, tp->vsize, (char *)tp->vsel);
 
703
      status = SCFCLO(newtid);
 
704
      }
 
705
   } 
 
706
 
 
707
 
 
708
if ((tp->tflags & (TBL__READONLY|TBL__MODIFIED)) == TBL__MODIFIED) 
 
709
   {
 
710
   if_not (tp->tflags & TBL__KEEPVERS) tp->version = TBL_VERSION;
 
711
        
 
712
   /* If ALL is selected, correct number of selected rows       */
 
713
 
 
714
   if ((tp->selected < 0) && (tp->select == '\1')) tp->selected = tp->rows;
 
715
 
 
716
   /* write descriptors */
 
717
 
 
718
   status = SCDWRI(tp->imno, TBL_Ddtypes, tp->dtypes, 1,tp->colitems, &dunit);
 
719
   if (status == ERR_NORMAL)
 
720
      status = SCDWRI(tp->imno, TBL_Doffset, tp->offset,1,tp->colitems, &dunit);
 
721
   if (status == ERR_NORMAL)
 
722
      status = SCDWRI(tp->imno, TBL_Dmain, &tp->acols,1,TBL_Dmain_SIZE,&dunit);
 
723
   if (status != ERR_NORMAL) goto error;
 
724
   }
 
725
 
 
726
if_not  (tp->tflags & TBL__MAPPED) 
 
727
   {                                            /* Must write everything */
 
728
   if ((status = TBL_WR (tp)))       return(status);
 
729
 
 
730
   osmmfree(tp->addres);
 
731
   tp->addres = (char *) 0;    /* MP 920909 */
 
732
   }
 
733
 
 
734
for (i=0; i<tp->nbuf; i++)
 
735
   {
 
736
   bp = tp->tbuf+i;
 
737
   if (bp && bp->buf) osmmfree(bp->buf);
 
738
   }
 
739
 
 
740
error:                                  /* error in SC routines */
 
741
if (status)
 
742
   {
 
743
   TBL_enter("TCTUNM problems");
 
744
   TBL_errs(tid, status, 0);
 
745
   }
 
746
return (status);
 
747
}
 
748
 
 
749
int TCTID(name)
 
750
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
751
.PURPOSE Find number from Name
 
752
.RETURNS Corresponding tid / -1 if not found
 
753
--------------------------------------------------------------------*/
 
754
        char *name;     /* IN: Name to look for */
 
755
{
 
756
  return (TBL_tid(name));
 
757
}
 
758
 
 
759
int TCTINI(name, storage, mode, allcol, allrow, tid)
 
760
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
761
.PURPOSE
 
762
        Initializes table file on disk and in memory
 
763
.ALGORITHM
 
764
        Creates output file and opens it
 
765
        according to the desired storage option and mode. 
 
766
        The storage option can be by records (F_RECORD) or
 
767
        transposed (F_TRANS). 
 
768
        The openning mode can be
 
769
        F_O_MODE for output or F_X_MODE for scratch. 
 
770
        
 
771
        The mode may include modifiers F_MAP_FORCE to force the
 
772
        mapping, F_EIO_FORCE to force an elementary i/o mode,
 
773
        F_ALL_FORCE to force exact numbers of lines / cols. 
 
774
        In this last case (F_ALL_FORCE), the number of physical
 
775
        columns to allocate may be given in the 2 leftmost bytes of mode,
 
776
        i.e. mode = (physical_columns*2**16 + F_ALL_FORCE + mode)
 
777
.RETURNS
 
778
        Status
 
779
------------------------------------------------------------------*/
 
780
        char    *name;          /* IN : table name              */
 
781
        int    storage;         /* IN : physical structure on disk */
 
782
        int     mode;           /* IN : opening mode           */
 
783
        int     allcol;         /* IN : number of words per record alloc.*/
 
784
        int     allrow;         /* IN : number of rows allocated */
 
785
        int     *tid;           /* MOD: table identifier (try to keep it) */
 
786
 
 
787
{
 
788
TABLE   *tp;
 
789
 
 
790
int     status, dummy;
 
791
int     imno, len, acol, arow, colitems;
 
792
 
 
793
struct FCT_STRUCT  *fctpntr;
 
794
 
 
795
 
 
796
 
 
797
 
 
798
 
 
799
tp = (TABLE *)0;
 
800
acol = (allcol <= 0) ? TBL_DALCOL : allcol ;
 
801
arow = (allrow <= 0) ? TBL_DALROW : allrow ;
 
802
 
 
803
                        /* Restrictions: Rows multiple of 8, columns odd.
 
804
                         * This ensures alignments on 8-byte boundaries */
 
805
colitems = 0;
 
806
if (mode & F_ALL_FORCE)
 
807
   {
 
808
   colitems = mode >> 16;
 
809
   }
 
810
else
 
811
   {
 
812
   arow = ((arow+7)>>3)<<3;
 
813
   if (!(acol&1)) acol++;
 
814
   }
 
815
if (colitems == 0) colitems = MIN (acol,COLS_MAX);
 
816
 
 
817
            
 
818
len  = arow * (acol + 1);
 
819
imno = 0;
 
820
  
 
821
if (mode == F_FO_MODE)                  /* set in fitsrhd() */
 
822
   {
 
823
   dummy = 1;
 
824
   mode = F_O_MODE;
 
825
   status = SCFCRE(name,D_R4_FORMAT,mode&0xf,F_FTBL_TYPE,len,&imno);
 
826
   }
 
827
else
 
828
   {
 
829
   dummy = 0;
 
830
   status = SCFCRE(name,D_R4_FORMAT,mode&0xf,F_TBL_TYPE,len,&imno);
 
831
   }
 
832
if (status != ERR_NORMAL) goto error;
 
833
                                            /* initialize control variables */
 
834
if (TBL_new(imno) < 0)  
 
835
   return(TBL_errf(ERR_TBLFUL, "too many tables, can't create %s", name));
 
836
 
 
837
*tid = imno;
 
838
tp = TBL_ptr(imno);
 
839
 
 
840
fctpntr = FCT.ENTRIES + imno;
 
841
tp->phname = TBL_ssave(fctpntr->NAME);          /* use cleaned name */
 
842
tp->usname = (char *)0;
 
843
tp->imno   = imno;
 
844
tp->acols = acol;
 
845
tp->arows = arow;
 
846
tp->cols = 0;
 
847
tp->rows = 0;
 
848
tp->kcol = 0;
 
849
tp->scol = 0;
 
850
tp->swise = storage;
 
851
tp->version= TBL_VERSION;
 
852
tp->colitems = colitems;
 
853
tp->selected = -1;                              /* unknown */
 
854
tp->tflags = 0;
 
855
tp->select = 0;
 
856
if (dummy == 1)
 
857
   tp->intlFITS = 'F';                  /* internal FITS table */
 
858
else
 
859
   tp->intlFITS = ' ';
 
860
                                        /* initialize columns for dtype */
 
861
tp->dtypes = (int *)osmmget(2*sizeof(int)*tp->colitems);
 
862
tp->offset = tp->dtypes + tp->colitems;
 
863
TBL_setcols (tp);
 
864
                                        /* write basic descriptors */
 
865
status = SCDWRI(tp->imno, TBL_Ddtypes, tp->dtypes, 1,tp->colitems, &dunit);
 
866
if (status != ERR_NORMAL) goto error;
 
867
 
 
868
status = SCDWRI(tp->imno, TBL_Doffset, tp->offset, 1,tp->colitems, &dunit);
 
869
if (status != ERR_NORMAL) goto error;
 
870
 
 
871
status = SCDWRI(tp->imno, TBL_Dmain, &tp->acols,1,TBL_Dmain_SIZE,&dunit);
 
872
if (status != ERR_NORMAL) goto error;
 
873
 
 
874
status = do_map(tp, mode);              /* map file */
 
875
if (status != ERR_NORMAL) goto error;
 
876
 
 
877
if (tp->intlFITS == 'F')                /* we have to write some data */
 
878
   {                                    /* because TCSINI uses SCFGET ... */
 
879
   status = dummyPUT(imno,len);
 
880
   if (status != ERR_NORMAL) goto error;
 
881
   }
 
882
 
 
883
TCSINI (*tid);
 
884
 
 
885
return (status);
 
886
 
 
887
 
 
888
error:
 
889
if (tp) osmmfree (tp->phname),TBL_kill(tp->imno);
 
890
if (status < ERR_TBLFUL)                        /* SC error     */
 
891
   MID_ERROR("MIDAS","TCTINI: ",status,1);
 
892
 
 
893
return (status);
 
894
}
 
895
/*
 
896
 
 
897
*/
 
898
 
 
899
 
 
900
int TCTMAP(tid, addr)
 
901
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
902
.PURPOSE Maps complete Table
 
903
.RETURNS status
 
904
------------------------------------------------------------------*/
 
905
        int     tid;    /* IN : table id                */
 
906
        char    **addr; /* OUT: Where table Mapped      */
 
907
{
 
908
        TABLE_BUF *bp;          /* MOD: The buffer concerned    */
 
909
        TABLE   *tp;
 
910
        unsigned char *pmap;
 
911
        int     status;
 
912
        int     i;
 
913
 
 
914
 
 
915
 
 
916
  tp = TBL_ptr(tid);
 
917
  if ((status = CheckTable(tp)))        return(TBL_errs(tid, status,0));
 
918
 
 
919
  if (tp->tflags & TBL__MAPPED) {       /* Already Done */
 
920
        *addr = tp->addres;
 
921
        return(status);
 
922
  }
 
923
  if (tp->tflags & TBL__EIO) {          /* Verify all empty */
 
924
        for (i = tp->nbuf, bp = tp->tbuf; (--i >= 0) && (bp->size == 0); bp++);
 
925
  } else {                              /* Just check bitmap    */
 
926
        i = sizeof(float)*(tp->acols + 1) * tp->arows;
 
927
        i = (1 + (i|0xffff)) >> 16;
 
928
        for (pmap = tp->loaded_map; (--i >= 0) && (*pmap == 0); pmap++) ;
 
929
  }
 
930
 
 
931
  if (i >= 0)   status = ERR_TBLMAP;
 
932
  if (status) {
 
933
        TBL_errf(status, "Table partly mapped. First Unmap table %s", 
 
934
                tp->phname);
 
935
        return(status);
 
936
  }
 
937
                        /* Free allocated memory for Buffers    */
 
938
  osmmfree((char *)tp->tbuf); 
 
939
  osmmfree((char *)tp->loaded_map); 
 
940
  osmmfree((char *)tp->vsel); 
 
941
        
 
942
  i = F_MAP_FORCE | (tp->tflags & TBL__READONLY ? F_I_MODE : F_IO_MODE);
 
943
  status = do_map (tp, i);
 
944
 
 
945
  return (status);
 
946
}
 
947
 
 
948
int TCTOPN(name,mode,tid)
 
949
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
950
.PURPOSE
 
951
        Reads  table file from disk.
 
952
.ALGORITHM
 
953
        Opens table file 
 
954
        according to the desired mode. The openning mode can be
 
955
        F_I_MODE for input, F_D_MODE for descriptors only, 
 
956
        F_IO_MODE for update. 
 
957
 
 
958
        The mode may include modifiers F_MAP_FORCE to force the
 
959
        mapping, or F_EIO_FORCE to force an elementary i/o mode.
 
960
.RETURNS
 
961
        Status
 
962
------------------------------------------------------------------*/
 
963
        char    *name;          /* IN : table name              */
 
964
        int     mode;           /* IN : openning mode    */
 
965
        int     *tid;           /* MOD: table identifier (try to keep it) */
 
966
{
 
967
TABLE   *tp;
 
968
 
 
969
int     imno, maxval;
 
970
int  dnull=-1;
 
971
int  status, flags[3];
 
972
 
 
973
 
 
974
 
 
975
                                        /* opens file                   */
 
976
                      
 
977
flags[0] = ERRO_CONT;                   /* continue always, and */
 
978
flags[1] = ERRO_LOG;                    /* log nothing, and */
 
979
flags[2] = ERRO_DISP;                   /* display nothing */
 
980
ERRO_CONT = 1;;
 
981
ERRO_LOG = 0;
 
982
ERRO_DISP = 0;
 
983
 
 
984
  imno = *tid;                  /* in case a specific `index' is wanted... */
 
985
  if ((status = SCFOPN(name, D_R4_FORMAT, 0, F_TBL_TYPE, &imno)))
 
986
     {
 
987
     SCECNT("PUT", flags, flags+1, flags+2);
 
988
     return(TBL_errf(status,"Error opening Table %s",name));
 
989
     }
 
990
 
 
991
  if (TBL_new(imno) < 0)        /* Not too many opened tables?  */
 
992
     {
 
993
     TBL_errf(ERR_TBLFUL, "too many tables, can't open %s", name);
 
994
     return (ERR_TBLFUL);
 
995
     }
 
996
                
 
997
  *tid = imno;
 
998
  tp = TBL_ptr(imno);
 
999
  tp->phname = TBL_ssave(name);
 
1000
  tp->usname = (char *)0;
 
1001
  tp->tflags = ((mode&0xf) == F_I_MODE ? TBL__READONLY : 0);    
 
1002
  tp->imno   = imno;
 
1003
  tp->addres = (char *)0;
 
1004
  tp->select = 0;
 
1005
                                                /* get control variables */
 
1006
  status = SCDRDI(tp->imno, TBL_Dmain,1,TBL_Dmain_SIZE,
 
1007
                  &maxval,&tp->acols,&dunit,&dnull);
 
1008
  if (status != ERR_NORMAL) goto error;
 
1009
 
 
1010
  if (maxval < 8)       tp->version = 0;
 
1011
  if (maxval < 9)       tp->colitems = MAX (tp->acols, tp->cols);
 
1012
  if (maxval <10)       tp->selected = -1;      /* Unknown */
 
1013
  if (tp->selected == -1) tp->selected = tp->rows;
 
1014
 
 
1015
  if (tp->swise & F_B_VIEW) 
 
1016
     {
 
1017
        int     vid, oldtid, kk;
 
1018
        TABLE *vp, *oldtp;
 
1019
        char    view[1+TBL_Dview_SIZE];
 
1020
 
 
1021
        status = SCDRDC(tp->imno, TBL_Dview, 1,1,TBL_Dview_SIZE, &maxval,
 
1022
                        view, &dunit, &dnull);
 
1023
        if (status != ERR_NORMAL) 
 
1024
           {
 
1025
           TBL_errf (status, "Bad View: %s", name);
 
1026
           goto error;
 
1027
           }
 
1028
 
 
1029
        view[maxval] = '\0';
 
1030
        if (osfdate(view) > osfdate(name))
 
1031
           TBL_errf (-1, "table '%s' refered by view '%s' was modified ?",
 
1032
                     view, name);
 
1033
 
 
1034
        oldtp = tp;             /* save table pointer */
 
1035
        oldtid = *tid;
 
1036
 
 
1037
        ERRO_CONT = flags[0];
 
1038
        ERRO_LOG = flags[1];                   /* reset error flags */
 
1039
        ERRO_DISP = flags[2];                   /* reset error flags */
 
1040
        vid = -1;
 
1041
        status = TCTOPN (view, F_I_MODE, &vid);
 
1042
        if (status != ERR_NORMAL)       goto error;
 
1043
 
 
1044
        vp = TBL_ptr(vid);
 
1045
        vp->vno    = oldtp->imno;
 
1046
 
 
1047
        if (oldtp->tflags & TBL__READONLY)      vp->tflags |= TBL__VREADONLY;
 
1048
 
 
1049
                                        /* Read Selection Table */
 
1050
        kk = sizeof(float);
 
1051
        vp->vsize = 1 + (vp->rows>>3);
 
1052
        if (vp->vsize < kk) vp->vsize = kk;     /* space for at least 1 value */
 
1053
        vp->vsel = (unsigned char *)osmmget( vp->vsize );
 
1054
        vp->usname = TBL_ssave(name);
 
1055
 
 
1056
        kk = tp->vsize>>2;      /* really tp->vsize, not vp->vsize? KB 050603 */
 
1057
        if (kk > vp->vsize)
 
1058
           {
 
1059
           char mesg[80];
 
1060
           (void) sprintf(mesg,
 
1061
                  "tp->vsize>>2 = %d, vp->vsize = %d, so we truncate...",
 
1062
                  kk,vp->vsize);
 
1063
           SCTPUT(mesg);
 
1064
           kk = vp->vsize;
 
1065
           }
 
1066
        /* status = SCFGET (vp->vno,1,tp->vsize>>2,&maxval,(char *)vp->vsel); */
 
1067
        status = SCFGET (vp->vno, 1, kk, &maxval, (char *)vp->vsel);
 
1068
 
 
1069
        oldtp->tflags |= TBL__MAPPED;   /* to avoid going through TBL_WR() */
 
1070
        TCTCLO(oldtid);
 
1071
 
 
1072
        *tid = vid;                     /* return the new table id */
 
1073
        goto error;
 
1074
  }
 
1075
        
 
1076
                                                /* Map File             */
 
1077
  status = do_map(tp, mode);
 
1078
  if (status != ERR_NORMAL) goto error;
 
1079
                                                /* Get Column datatypes */
 
1080
  tp->dtypes = (int *)osmmget(2*sizeof(int)*tp->colitems);
 
1081
  tp->offset = tp->dtypes + tp->colitems;
 
1082
 
 
1083
  status = SCDRDI(tp->imno, TBL_Ddtypes,1,tp->colitems,&maxval,
 
1084
          tp->dtypes,&dunit,&dnull);
 
1085
  if (status != ERR_NORMAL) goto error;
 
1086
 
 
1087
  if (tp->version)  status = SCDRDI(tp->imno, TBL_Doffset,1,tp->colitems,
 
1088
                &maxval,tp->offset,&dunit,&dnull);
 
1089
                                                /* layout of physical columns */
 
1090
  TBL_setcols (tp);
 
1091
 
 
1092
                        /* Convert NULL values if required */
 
1093
  if (tp->tflags & TBL__BADNULLS) 
 
1094
     {
 
1095
     convert_nulls(tp);
 
1096
     tp->tflags &= ~TBL__BADNULLS;
 
1097
     }
 
1098
 
 
1099
 
 
1100
 
 
1101
  error:
 
1102
  ERRO_CONT = flags[0];                         /* reset error flags */
 
1103
  ERRO_LOG = flags[1]; 
 
1104
  ERRO_DISP = flags[2]; 
 
1105
  if ((status) && (status < ERR_TBLFUL))                /* SC error     */
 
1106
        TBL_errs(imno, status, 0);
 
1107
  return ( status );
 
1108
}
 
1109
/*
 
1110
 
 
1111
*/
 
1112
 
 
1113
int TCTVIS(tid,name)
 
1114
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
1115
.PURPOSE
 
1116
        Reads  table file from disk.
 
1117
.ALGORITHM
 
1118
        Opens table file 
 
1119
        according to the desired mode. The openning mode can be
 
1120
        F_I_MODE for input, F_D_MODE for descriptors only, 
 
1121
        F_IO_MODE for update. 
 
1122
 
 
1123
        The mode may include modifiers F_MAP_FORCE to force the
 
1124
        mapping, or F_EIO_FORCE to force an elementary i/o mode.
 
1125
.RETURNS
 
1126
        Status
 
1127
------------------------------------------------------------------*/
 
1128
        int     tid;            /* MOD: table identifier (try to keep it) */
 
1129
        char    *name;          /* IN : table name              */
 
1130
{
 
1131
        TABLE   *tp;
 
1132
 
 
1133
        
 
1134
  tp = TBL_ptr(tid);
 
1135
  if (tp->usname) {
 
1136
         strncpy(name,tp->usname,60);
 
1137
         return(1);
 
1138
         }
 
1139
  else return(0);
 
1140
}