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

« back to all changes in this revision

Viewing changes to libsrc/os/unix/osd.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        osd
 
31
.LANGUAGE    C
 
32
.AUTHOR      IPG-ESO Garching
 
33
.CATEGORY    Host operating system interfaces. Data file i/o.
 
34
.COMMENTS    
 
35
             Handling of data files. These routines access data in binary
 
36
             format. Data files are accessed via direct i/o
 
37
             in a synchronous way.
 
38
             Files are referenced by the physical filename in the open 
 
39
             function.
 
40
             A file identifier is returned by this function to be used 
 
41
             in later i/o operations. 
 
42
             Associated to each file there is a pointer to locate the current 
 
43
             file position.
 
44
             The routines return always
 
45
             a non-negative integer number on successful return.
 
46
             Otherwise, a value of -1 is set to indicate an error
 
47
             condition and the variable ``oserror'' contains the 
 
48
             symbolic error code. On read on end of file, the value of -1 is
 
49
             also returned.
 
50
.VERSION  0.0   25-Aug-1986   Definition     J.D. Ponz
 
51
.VERSION  1.0   28-Nov-1986   Programmation  B.   Pirenne
 
52
.VERSION  1.1   14-Apr-1987   Upgrade performance B. Pirenne
 
53
.VERSION  1.2   15-Jul-1987   Include asynchronous file access B. Pirenne
 
54
.VERSION  1.3   07-Dec-1987   Upgrade performance and compact the code 
 
55
                                 I. Suisalu
 
56
.VERSION  1.4   31-May-1988   Cosmetic changes. C. Guirao.
 
57
.VERSION  1.5   04-Oct-1988   osdopen creates the file if non-existant.
 
58
.VERSION  1.6   21-Jun-1989   O_TRUNC added at open in WRITE mode.
 
59
                                and open (path, flags, -1) now.
 
60
.VERSION  1.7   07-Nov-1989   Simplified osdopen
 
61
.VERSION  1.8   05-Feb-1990   Default creat mode is 0644 (no executre right)
 
62
.VERSION  1.9   14-Mar-1990   Removed bug is osdread (set errno to 0)
 
63
.VERSION  1.10  19-Dec-1990   Not checking FNAME_LEN any more CG.
 
64
.VERSION  1.11  21-Oct-1991   fsync() removed. Not portable. CG.
 
65
.VERSION  2.1   29-May-1992   open creates the file with default umask 0666.CG
 
66
.VERSION  3.1   09-Mar-1994   Decompressing in the fly. CG.
 
67
 
 
68
 090325         last modif
 
69
 
 
70
------------------------------------------------------------*/
 
71
/*
 
72
 * Define _POSIX_SOURCE to indicate
 
73
 * that this is a POSIX program
 
74
 */
 
75
#define _POSIX_SOURCE 1
 
76
 
 
77
#include <sys/types.h>
 
78
#include <sys/stat.h>
 
79
#include <string.h>
 
80
#include <stdio.h>
 
81
#include <stdlib.h>
 
82
#include <unistd.h>
 
83
#include <fcntl.h>
 
84
#include <errno.h>
 
85
#include <osparms.h>
 
86
#include <proto_os.h>           /* ANSI-C prototyping */
 
87
 
 
88
#define MAX_TABLE_ENTRY 20
 
89
static struct DECOMPRESS
 
90
   {
 
91
   int entry;
 
92
   int longest_suffix;
 
93
   char *suffix[MAX_TABLE_ENTRY + 2];
 
94
   char *command[MAX_TABLE_ENTRY + 2];
 
95
   } decompress =
 
96
{
 
97
2, 2,
 
98
{
 
99
".Z", ".z"},
 
100
{
 
101
"zcat", "gunzip -c"},};
 
102
 
 
103
static int decomp_table_read = 0;
 
104
static FILE *file_ptr[_NFILE_];
 
105
extern FILE *popen ();          /* Not defined in <stdio.h> of OSF/1 */
 
106
extern int pclose();
 
107
 
 
108
 
 
109
#ifdef O_TRUNC
 
110
#   define O_write              (O_WRONLY | O_TRUNC | O_CREAT)
 
111
#else
 
112
#   define O_write              (O_WRONLY | O_CREAT)
 
113
#endif
 
114
#define OSDMASK         0666
 
115
 
 
116
 
 
117
/*
 
118
 * read_decomp_table() " reads the file containing this table from the
 
119
 * environment $DECOMPRESS_TABLE, otherwise uses $MID_INCLUDE/decompress.dat
 
120
 * 
 
121
 * The syntax of this file must be followed strictly:
 
122
 *  - Only '#' as the first character makes a line in comments.
 
123
 *  - Separators are blanks or tabs.
 
124
 *  - Suffixes are in the first column and without quotes.
 
125
 *  - Commands are in the second column. Double quotes are required if the
 
126
 *    command contains blanks.
 
127
 *  - Commands can contain the character '*' that represents the file to be
 
128
 *    decompressed. NOTE: only the first '*' is expanded.
 
129
 *  - Any thing after the second column is ignored.
 
130
 *  - Incomplete entries are ignored (i.g. only the suffix)
 
131
 *  - Only the first MAX_TABLE_ENTRY (20) entries are read, the rest is ignored.
 
132
 */
 
133
static void read_decomp_table ()
 
134
 
 
135
{
 
136
char *getenv ();
 
137
static char *decomp_table_file = NULL;
 
138
FILE *fd, *fopen ();
 
139
int i, suffix_length;
 
140
char *q, *mid_include;
 
141
char buf[100], suffix[8], command[80];
 
142
 
 
143
  /* check if DECOMPRESS_TABLE environment is defined */
 
144
if ((decomp_table_file = getenv ("DECOMPRESS_TABLE")) == NULL)
 
145
   {
 
146
   if ((mid_include = getenv ("MID_INCLUDE")) == NULL)
 
147
      {
 
148
      /* Using the built-in table */
 
149
      /* printf("No DECOMPRESS_TABLE or MID_INCLUDE definition\n"); */
 
150
      return;
 
151
      }
 
152
   decomp_table_file =
 
153
   malloc ((size_t)(strlen (mid_include) + strlen ("/decompress.dat") + 1));
 
154
   strcpy (decomp_table_file, mid_include);
 
155
   strcat (decomp_table_file, "/decompress.dat");
 
156
   }
 
157
 
 
158
if ((fd = fopen (decomp_table_file, "r")) == NULL)
 
159
   {
 
160
   /* Using the built-in table */
 
161
   /* printf("Cannot open DECOMPRESS_TABLE %s\n",decomp_table_file); */
 
162
   return;
 
163
   }
 
164
 
 
165
  /* reads the contents of decompressed table file */
 
166
while (fgets (buf, sizeof (buf), fd) != NULL
 
167
       && decompress.entry < MAX_TABLE_ENTRY)
 
168
   {
 
169
   if (buf[0] == '#')
 
170
   continue;
 
171
   for (q = buf; *q && ((*q == ' ') || (*q == '\t')); q++);
 
172
   for (i = 0; (*q != '\n') && (*q != ' ') && (*q != '\t'); q++)
 
173
   suffix[i++] = *q;
 
174
   if (i)
 
175
   suffix[i] = '\0';
 
176
   else
 
177
   continue;
 
178
   for (; *q && ((*q == ' ') || (*q == '\t')); q++);
 
179
   if (*q == '"')
 
180
      {
 
181
      q++;
 
182
      for (i = 0; (*q != '\n') && (*q != '"'); q++)
 
183
      command[i++] = *q;
 
184
      }
 
185
   else
 
186
      {
 
187
      for (i = 0; (*q != '\n') && (*q != ' ') && (*q != '\t'); q++)
 
188
      command[i++] = *q;
 
189
      }
 
190
   if (i)
 
191
   command[i] = '\0';
 
192
   else
 
193
   continue;
 
194
   suffix_length = strlen (suffix);
 
195
   decompress.suffix[decompress.entry] = malloc ((size_t)(suffix_length + 1));
 
196
   decompress.command[decompress.entry] = malloc ((size_t)(strlen (command) + 1));
 
197
   strcpy (decompress.suffix[decompress.entry], suffix);
 
198
   strcpy (decompress.command[decompress.entry], command);
 
199
   if (suffix_length > decompress.longest_suffix)
 
200
   decompress.longest_suffix = suffix_length;
 
201
   decompress.entry++;
 
202
   }
 
203
}
 
204
 
 
205
static int match_preffix (phname)
 
206
char *phname;
 
207
{
 
208
int i;
 
209
int n_suffix;
 
210
 
 
211
for (i = decompress.entry - 1; i >= 0; i--)
 
212
   {
 
213
   n_suffix = strlen (decompress.suffix[i]);
 
214
   if (!strcmp
 
215
       (&phname[strlen (phname) - n_suffix], decompress.suffix[i]))
 
216
   return (i);
 
217
   }
 
218
return (-1);
 
219
}
 
220
 
 
221
 
 
222
static int match_compressed_file (phname, comp_phname)
 
223
char *phname;
 
224
char **comp_phname;
 
225
{
 
226
struct stat buf;
 
227
int i;
 
228
 
 
229
*comp_phname = malloc ((size_t)(strlen (phname) + decompress.longest_suffix + 1));
 
230
for (i = decompress.entry - 1; i >= 0; i--)
 
231
   {
 
232
   strcpy (*comp_phname, phname);
 
233
   strcat (*comp_phname, decompress.suffix[i]);
 
234
   if (stat (*comp_phname, &buf) == 0 && S_ISREG (buf.st_mode))
 
235
   return (i);
 
236
   }
 
237
free (*comp_phname);
 
238
return (-1);
 
239
}
 
240
 
 
241
static char *get_command (phname, match)
 
242
char *phname;
 
243
int match;
 
244
{
 
245
char *command;
 
246
char *ptr_to_star;
 
247
 
 
248
command =
 
249
calloc (strlen (decompress.command[match]) + strlen (phname) + 2, 1);
 
250
 
 
251
if ((ptr_to_star = strchr (decompress.command[match], '*')) == NULL)
 
252
   {
 
253
   strcpy (command, decompress.command[match]);
 
254
   strcat (command, " ");
 
255
   strcat (command, phname);
 
256
   }
 
257
else
 
258
   {
 
259
   strncpy (command, decompress.command[match],
 
260
            (int) (ptr_to_star - decompress.command[match]));
 
261
   ptr_to_star++;
 
262
   strcat (command, phname);
 
263
   strcat (command, ptr_to_star);
 
264
   }
 
265
return (command);
 
266
}
 
267
 
 
268
int osdopen (phname, mode)
 
269
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
270
.PURPOSE Open EXISTING binary data file for read or write. The variable mode
 
271
         defines the way of opening the file as :
 
272
         READ, WRITE, READ_WRITE and APPEND.
 
273
         The file pointer is set to the beginning of the file.
 
274
.RETURNS Upon successful completion a positive number with the 
 
275
.RETURNS file identification is returned. (-1 otherwise).
 
276
.REMARKS System dependencies:
 
277
 -- UNIX: open(2)
 
278
------------------------------------------------------------*/
 
279
char *phname;                                    /* physical filename */
 
280
int mode;                                        /* open mode */
 
281
 
 
282
{
 
283
int fid, t;
 
284
int myerrno;
 
285
int match;
 
286
FILE *fpin;
 
287
char *command;
 
288
char *compressed_file;
 
289
 
 
290
 
 
291
switch (mode & 3)
 
292
   {
 
293
   case READ:                  /* open for read only */
 
294
   t = O_RDONLY;
 
295
   /*
 
296
    * Read the decompression table first 
 
297
    */
 
298
   if (!decomp_table_read)
 
299
      {
 
300
      decomp_table_read++;
 
301
      read_decomp_table ();
 
302
      }
 
303
   /* 
 
304
    * Check if filename contains a suffix  
 
305
    */
 
306
   if ((match = match_preffix (phname)) != -1)
 
307
   command = get_command (phname, match);
 
308
   /* 
 
309
    * Otherwise try to open filename 
 
310
    */
 
311
   else if ((fid = open (phname, t, OSDMASK)) > 0)
 
312
   return (fid);
 
313
   /* 
 
314
    * Otherwise try to find filename + suffix 
 
315
    */
 
316
   else
 
317
      {
 
318
      myerrno = errno;
 
319
      if ((match =
 
320
           match_compressed_file (phname, &compressed_file)) != -1)
 
321
         {
 
322
         command = get_command (compressed_file, match);
 
323
         free (compressed_file);
 
324
         }
 
325
      /* 
 
326
       * Otherwise return the error returned by open(phname) 
 
327
       */
 
328
      else
 
329
         {
 
330
         oserror = myerrno;
 
331
         return (-1);
 
332
         }
 
333
      }
 
334
 
 
335
   /* 
 
336
    * Open decompress command as a pipe 
 
337
    */
 
338
   printf ("%s\n", command);
 
339
   if ((fpin = popen (command, "r")) == NULL)
 
340
      {
 
341
      free (command);
 
342
      oserror = errno;
 
343
      return (-1);
 
344
      }
 
345
   free (command);
 
346
   fid = fileno (fpin);
 
347
   if (fid >= _NFILE_)
 
348
      {
 
349
      oserror = EINVAL;
 
350
      return (-2);
 
351
      }
 
352
   file_ptr[fid] = fpin;
 
353
   return (fid);
 
354
   break;
 
355
   case WRITE:                 /* open for write only */
 
356
   t = O_write;
 
357
   break;
 
358
   case READ_WRITE:            /* open for read-write */
 
359
   t = O_RDWR;
 
360
   break;
 
361
   case APPEND:                /* open for append */
 
362
   t = O_APPEND | O_WRONLY;
 
363
   break;
 
364
   default:
 
365
   t = O_RDWR;
 
366
   }
 
367
 
 
368
if ((fid = open (phname, t, OSDMASK)) == -1)
 
369
   oserror = errno;
 
370
 
 
371
return (fid);
 
372
}
 
373
 
 
374
int osdclose (fid)
 
375
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
376
.PURPOSE Closes data file. The argument fid is the file identification
 
377
         obtained from osdopen.
 
378
.RETURNS Value 0 on normal return. (-1 otherwise).
 
379
.REMARKS System dependencies:
 
380
 -- UNIX: close(2)
 
381
------------------------------------------------------------*/
 
382
int fid;                                         /* file identification */
 
383
 
 
384
{
 
385
FILE *fd;
 
386
 
 
387
 
 
388
if (fid < 3)
 
389
   {                    /* fid should not be stdin, stdout, stderr */
 
390
   return (-1);
 
391
   }
 
392
 
 
393
if (fid >= _NFILE_ || ((fd = file_ptr[fid]) == NULL))
 
394
   {
 
395
   if (close (fid) == -1)
 
396
      {
 
397
      oserror = errno;
 
398
      return (-1);
 
399
      }
 
400
   }
 
401
else
 
402
   {
 
403
   file_ptr[fid] = NULL;
 
404
   if (pclose (fd) == -1)
 
405
      {
 
406
      oserror = errno;
 
407
      return (-1);
 
408
      }
 
409
   }
 
410
return (0);
 
411
}
 
412
 
 
413
int osdread (fid, pbuf, nobyt)
 
414
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
415
.PURPOSE Synchronous read from a data file. 
 
416
         The argument fid is the file identification
 
417
         obtained from osdopen. osdread reads nobyt bytes from the current
 
418
         file position and stores the information into the buffer
 
419
         pointed by pbuf. On devices capable of seeking, the read starts at the
 
420
         position of the file pointer associated with fid.
 
421
         Upon return the pointer is incremented by the number of bytes actually
 
422
         read.
 
423
.RETURNS Number of bytes actually read. (-1 in case of failure or end of file).
 
424
.REMARKS System dependencies:
 
425
 -- UNIX: read(2)
 
426
------------------------------------------------------------*/
 
427
int fid;                     /* file identification */
 
428
char *pbuf;                  /* pointer to input buffer */
 
429
size_t nobyt;                /* number of input bytes */
 
430
 
 
431
{
 
432
int nread;
 
433
 
 
434
 
 
435
 
 
436
errno = 0;                      /* must be initialized... */
 
437
 
 
438
nread = (int) read (fid, (void *) pbuf, nobyt);
 
439
if (nread > 0) return (nread); 
 
440
 
 
441
oserror = errno;                /* error in reading file or at EOF */
 
442
return (-1);
 
443
}
 
444
 
 
445
 
 
446
int osdofread (fid, address, pbuf, nobyt)
 
447
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
448
.PURPOSE move file pointer to address + read from there
 
449
         The argument fid is the file identification
 
450
         obtained from osdopen. The address defines
 
451
         the pointer position in bytes relative to the
 
452
         start of the file
 
453
.RETURNS no. of bytes read
 
454
.REMARKS System dependencies:
 
455
 -- UNIX: lseek(2)
 
456
------------------------------------------------------------*/
 
457
int fid;                                         /* file identification */
 
458
off_t address;                                    /* file pointer */
 
459
char *pbuf;                                      /* pointer to input buffer */
 
460
size_t nobyt;                                  /* number of input bytes */
 
461
 
 
462
{
 
463
 
 
464
if (lseek (fid, address, SEEK_SET) != (off_t)-1)
 
465
   return ((int) read (fid, (void *) pbuf, nobyt));
 
466
else
 
467
   return (-1);
 
468
}
 
469
 
 
470
 
 
471
int osdwrite (fid, pbuf, nobyt)
 
472
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
473
.PURPOSE Synchronous write into a data file.
 
474
         The argument fid is the file identification
 
475
         obtained from osdopen. osdwrite writes nobyt bytes from the buffer
 
476
         pointed by pbuf. On devices capable of seeking, the write starts at
 
477
         the position of the file pointer associated with fid.
 
478
         Upon return the pointer is incremented by the number of bytes actually
 
479
         written. 
 
480
.RETURNS Number of characters actually written. (-1 in case of failure).
 
481
.REMARKS System dependencies:
 
482
 -- UNIX: write(2)
 
483
------------------------------------------------------------*/
 
484
int fid;                  /* file identification */
 
485
char *pbuf;               /* pointer to output buffer */
 
486
size_t nobyt;             /* number of output bytes */
 
487
 
 
488
{
 
489
int i;
 
490
 
 
491
if ((i = (int) write (fid, (void *) pbuf, nobyt)) == -1)
 
492
   oserror = errno;
 
493
 
 
494
return (i);
 
495
}
 
496
 
 
497
 
 
498
int osdofwrite (fid, address, pbuf, nobyt)
 
499
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
500
.PURPOSE move file pointer to address + write to there
 
501
         The argument fid is the file identification
 
502
         obtained from osdopen. The address defines
 
503
         the pointer position in bytes relative to the
 
504
         start of the file
 
505
.RETURNS no. of bytes read
 
506
.REMARKS System dependencies:
 
507
 -- UNIX: lseek(2)
 
508
------------------------------------------------------------*/
 
509
int fid;                    /* file identification */
 
510
off_t address;              /* file pointer */
 
511
char *pbuf;                 /* pointer to input buffer */
 
512
size_t nobyt;               /* number of input bytes */
 
513
 
 
514
{
 
515
 
 
516
if (lseek (fid, address, SEEK_SET) != (off_t)-1)
 
517
   return ((int) write (fid, (void *) pbuf, nobyt));
 
518
else
 
519
   return (-1);
 
520
}
 
521
 
 
522
 
 
523
off_t osdseek (fid, address, mode)
 
524
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
525
.PURPOSE moves the file pointer.
 
526
         The argument fid is the file identification
 
527
         obtained from osdopen. The address defines
 
528
         the pointer position in bytes relative to:
 
529
         start of the file, current position or end of the file as
 
530
         defined by the variable mode (FILE_START, FILE_CURRENT, FILE_END).
 
531
         (see midas/osparms.h). (i.e. : an address=0 and OS_START set means
 
532
         first byte of the file).
 
533
.RETURNS Upon successful completion, the resulting pointer position
 
534
.RETURNS measured in bytes is returned, in case of error -1L.
 
535
.REMARKS System dependencies:
 
536
 -- UNIX: lseek(2)
 
537
------------------------------------------------------------*/
 
538
int fid;                                         /* file identification */
 
539
off_t address;                                   /* file pointer */
 
540
int mode;                                        /* mode of addressing */
 
541
{
 
542
off_t offret;
 
543
 
 
544
offret = lseek (fid, address, mode);
 
545
if (offret == (off_t)-1) oserror = errno;
 
546
 
 
547
return (offret);
 
548
}
 
549
 
 
550
int osdputs (fid, pbuf)
 
551
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
552
.PURPOSE Synchronous write to a file a string of characters followed
 
553
        by a newline (end of record).
 
554
         The argument fid is the file identification obtained from osdopen.
 
555
.RETURNS Number of characters actually written. 
 
556
        -1 for error (oserror provides an explanation)
 
557
.REMARKS 
 
558
------------------------------------------------------------*/
 
559
int fid;                      /* IN : file identifier */
 
560
char *pbuf;                   /* IN : EOS-terminated string to write */
 
561
 
 
562
{
 
563
register char *p;
 
564
int i;
 
565
 
 
566
i = (int) strlen (pbuf);
 
567
p = pbuf + i++;
 
568
*p = '\n';
 
569
 
 
570
if ((i = osdwrite (fid, pbuf,(size_t) i)) == -1)
 
571
   oserror = errno;
 
572
 
 
573
*p = '\0';
 
574
return (i);
 
575
}
 
576
 
 
577
int osdwait ( /*fid */ )
 
578
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
579
.PURPOSE Waits for asynchronous input/output to be completed.
 
580
         The argument fid is the file identification
 
581
         obtained from osdopen. If the process is waiting for
 
582
         input/output operation, the execution of the process is suspended
 
583
         until the transfer is complete.
 
584
         !!! NOT IMPLEMENTED : RETURNS ALWAYS 0 !!!
 
585
.RETURNS The function returns 0 for success, and -1 if any error was
 
586
         detected.
 
587
.REMARKS System dependencies:
 
588
 -- UNIX: sync(2)
 
589
------------------------------------------------------------*/
 
590
                                /*int fid;*//* file identification */
 
591
{
 
592
return (0);
 
593
}