1
/*===========================================================================
2
Copyright (C) 1995-2009 European Southern Observatory (ESO)
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.
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.
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,
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
26
===========================================================================*/
28
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
.AUTHOR IPG-ESO Garching
33
.CATEGORY Host operating system interfaces. Data file i/o.
35
Handling of data files. These routines access data in binary
36
format. Data files are accessed via direct i/o
38
Files are referenced by the physical filename in the open
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
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
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
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.
70
------------------------------------------------------------*/
72
* Define _POSIX_SOURCE to indicate
73
* that this is a POSIX program
75
#define _POSIX_SOURCE 1
77
#include <sys/types.h>
86
#include <proto_os.h> /* ANSI-C prototyping */
88
#define MAX_TABLE_ENTRY 20
89
static struct DECOMPRESS
93
char *suffix[MAX_TABLE_ENTRY + 2];
94
char *command[MAX_TABLE_ENTRY + 2];
101
"zcat", "gunzip -c"},};
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 */
110
# define O_write (O_WRONLY | O_TRUNC | O_CREAT)
112
# define O_write (O_WRONLY | O_CREAT)
118
* read_decomp_table() " reads the file containing this table from the
119
* environment $DECOMPRESS_TABLE, otherwise uses $MID_INCLUDE/decompress.dat
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.
133
static void read_decomp_table ()
137
static char *decomp_table_file = NULL;
139
int i, suffix_length;
140
char *q, *mid_include;
141
char buf[100], suffix[8], command[80];
143
/* check if DECOMPRESS_TABLE environment is defined */
144
if ((decomp_table_file = getenv ("DECOMPRESS_TABLE")) == NULL)
146
if ((mid_include = getenv ("MID_INCLUDE")) == NULL)
148
/* Using the built-in table */
149
/* printf("No DECOMPRESS_TABLE or MID_INCLUDE definition\n"); */
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");
158
if ((fd = fopen (decomp_table_file, "r")) == NULL)
160
/* Using the built-in table */
161
/* printf("Cannot open DECOMPRESS_TABLE %s\n",decomp_table_file); */
165
/* reads the contents of decompressed table file */
166
while (fgets (buf, sizeof (buf), fd) != NULL
167
&& decompress.entry < MAX_TABLE_ENTRY)
171
for (q = buf; *q && ((*q == ' ') || (*q == '\t')); q++);
172
for (i = 0; (*q != '\n') && (*q != ' ') && (*q != '\t'); q++)
178
for (; *q && ((*q == ' ') || (*q == '\t')); q++);
182
for (i = 0; (*q != '\n') && (*q != '"'); q++)
187
for (i = 0; (*q != '\n') && (*q != ' ') && (*q != '\t'); q++)
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;
205
static int match_preffix (phname)
211
for (i = decompress.entry - 1; i >= 0; i--)
213
n_suffix = strlen (decompress.suffix[i]);
215
(&phname[strlen (phname) - n_suffix], decompress.suffix[i]))
222
static int match_compressed_file (phname, comp_phname)
229
*comp_phname = malloc ((size_t)(strlen (phname) + decompress.longest_suffix + 1));
230
for (i = decompress.entry - 1; i >= 0; i--)
232
strcpy (*comp_phname, phname);
233
strcat (*comp_phname, decompress.suffix[i]);
234
if (stat (*comp_phname, &buf) == 0 && S_ISREG (buf.st_mode))
241
static char *get_command (phname, match)
249
calloc (strlen (decompress.command[match]) + strlen (phname) + 2, 1);
251
if ((ptr_to_star = strchr (decompress.command[match], '*')) == NULL)
253
strcpy (command, decompress.command[match]);
254
strcat (command, " ");
255
strcat (command, phname);
259
strncpy (command, decompress.command[match],
260
(int) (ptr_to_star - decompress.command[match]));
262
strcat (command, phname);
263
strcat (command, ptr_to_star);
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:
278
------------------------------------------------------------*/
279
char *phname; /* physical filename */
280
int mode; /* open mode */
288
char *compressed_file;
293
case READ: /* open for read only */
296
* Read the decompression table first
298
if (!decomp_table_read)
301
read_decomp_table ();
304
* Check if filename contains a suffix
306
if ((match = match_preffix (phname)) != -1)
307
command = get_command (phname, match);
309
* Otherwise try to open filename
311
else if ((fid = open (phname, t, OSDMASK)) > 0)
314
* Otherwise try to find filename + suffix
320
match_compressed_file (phname, &compressed_file)) != -1)
322
command = get_command (compressed_file, match);
323
free (compressed_file);
326
* Otherwise return the error returned by open(phname)
336
* Open decompress command as a pipe
338
printf ("%s\n", command);
339
if ((fpin = popen (command, "r")) == NULL)
352
file_ptr[fid] = fpin;
355
case WRITE: /* open for write only */
358
case READ_WRITE: /* open for read-write */
361
case APPEND: /* open for append */
362
t = O_APPEND | O_WRONLY;
368
if ((fid = open (phname, t, OSDMASK)) == -1)
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:
381
------------------------------------------------------------*/
382
int fid; /* file identification */
389
{ /* fid should not be stdin, stdout, stderr */
393
if (fid >= _NFILE_ || ((fd = file_ptr[fid]) == NULL))
395
if (close (fid) == -1)
403
file_ptr[fid] = NULL;
404
if (pclose (fd) == -1)
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
423
.RETURNS Number of bytes actually read. (-1 in case of failure or end of file).
424
.REMARKS System dependencies:
426
------------------------------------------------------------*/
427
int fid; /* file identification */
428
char *pbuf; /* pointer to input buffer */
429
size_t nobyt; /* number of input bytes */
436
errno = 0; /* must be initialized... */
438
nread = (int) read (fid, (void *) pbuf, nobyt);
439
if (nread > 0) return (nread);
441
oserror = errno; /* error in reading file or at EOF */
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
453
.RETURNS no. of bytes read
454
.REMARKS System dependencies:
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 */
464
if (lseek (fid, address, SEEK_SET) != (off_t)-1)
465
return ((int) read (fid, (void *) pbuf, nobyt));
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
480
.RETURNS Number of characters actually written. (-1 in case of failure).
481
.REMARKS System dependencies:
483
------------------------------------------------------------*/
484
int fid; /* file identification */
485
char *pbuf; /* pointer to output buffer */
486
size_t nobyt; /* number of output bytes */
491
if ((i = (int) write (fid, (void *) pbuf, nobyt)) == -1)
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
505
.RETURNS no. of bytes read
506
.REMARKS System dependencies:
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 */
516
if (lseek (fid, address, SEEK_SET) != (off_t)-1)
517
return ((int) write (fid, (void *) pbuf, nobyt));
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:
537
------------------------------------------------------------*/
538
int fid; /* file identification */
539
off_t address; /* file pointer */
540
int mode; /* mode of addressing */
544
offret = lseek (fid, address, mode);
545
if (offret == (off_t)-1) oserror = errno;
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)
558
------------------------------------------------------------*/
559
int fid; /* IN : file identifier */
560
char *pbuf; /* IN : EOS-terminated string to write */
566
i = (int) strlen (pbuf);
570
if ((i = osdwrite (fid, pbuf,(size_t) i)) == -1)
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
587
.REMARKS System dependencies:
589
------------------------------------------------------------*/
590
/*int fid;*//* file identification */