]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/icepack/iceconvert/rdmc_mcopen.c
08-mar-2006 NvE Time offset correction in IceF2k extended to allow also a user define...
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / rdmc_mcopen.c
CommitLineData
f67e2651 1/****************************************************************************/
2/* rdmc_mcopen() opens a mc/data file */
3/* usage is like fopen(), format is BAIKAL_BIN_F for the baikal like binary */
4/* format, and DUMAND_ASCII_F for the DUMAND-like ascii format */
5/****************************************************************************/
6
7#undef RDMC_MCOPEN_DEBUG
8
9#include <string.h>
10#include <stdlib.h>
11#include <ctype.h>
12#include <stdio.h>
13///////////////#include <unistd.h>
14#include <sys/stat.h>
15
16#if defined(OSF1) || defined (SunOS) || defined(IRIX)
17#include <alloca.h>
18#endif
19
20
21#include "rdmc.h"
22#include "rdmc_local.h"
23
24
25#include "baikal.h"
26#include "amanda.h"
27#include "uwi.h"
28#include "dumand.h"
29
30
31FILE *rdmc_gzipopen(const char *name, const char *mode); /* open a gzip file */
32FILE *rdmc_bzipopen(const char *name, const char *mode); /* open a bzip file */
33FILE *rdmc_bzip2open(const char *name, const char *mode); /* open a bzip2 file */
34int rdmc_strsuf(const char *str, const char *suf); /* test for a suffix */
35FILE *rdmc_myopen(const char *name, const char *mode, int *piped);/*open a (compressed) file */
36char *rdmc_remote_pipe(const char *name, const char *mode); /* builds pipe command for rsh */
37char *rdmc_is_in_path(const char *program); /* is certain program in the path. */
38
39
40
41mcfile *rdmc_mcopen(const char *name, const char *mode, int format)
42{
43 mcfile *fp;
44 FILE *tf; /* temporary file pointer */
45 int r;
46 int fmode,zipped; /* read or write, and detected format */
47 char s[RDMC_MAXLINE];
48
49 /* test if format is allowed */
50 if ( 1
51#ifdef DUMAND_ASCII_F
52 && (format != DUMAND_ASCII_F)
53#endif
54#ifdef UWI_ASCII_F
55 && (format != UWI_ASCII_F)
56#endif
57#ifdef AMANDA_ASCII_F
58 && (format != AMANDA_ASCII_F)
59#endif
60#ifdef BAIKAL_BIN_F
61 && (format != BAIKAL_BIN_F )
62#endif
63 ){
64#ifdef RDMC_MCOPEN_DEBUG
65 rdmc_warnprintf("DEBUG: Unknown format %i", format);
66#endif
67 return (NULL);
68 }
69
70 /* now get the mode to open the file */
71 if (strstr(mode,"r") != NULL){ /* this is reading */
72 fmode = RDMC_READ_MODE;
73 } else if (strstr(mode,"w") != NULL){ /* this is writing */
74 fmode = RDMC_WRITE_MODE;
75 }else{ /* this is nonesensce */
76#ifdef RDMC_MCOPEN_DEBUG
77 rdmc_warnprintf("DEBUG: Unknown mode %s (not r or w)", mode);
78#endif
79 return (NULL);
80 }
81
82 /* allocate memory for the mcfile structure and initilize to 0*/
83 if ((fp = (mcfile *)calloc(1,sizeof(mcfile))) == NULL){
84#ifdef RDMC_MCOPEN_DEBUG
85 rdmc_warnprintf("DEBUG: Could not allocate mcfile structure");
86#endif
87 return (NULL);
88 }
89
90 if (name[0] != '\0') { /* if no stdin/out */
91 tf = rdmc_myopen(name, mode, &(zipped));
92 if (tf == NULL) { /* if open failed */
93 free(fp);
94#ifdef RDMC_MCOPEN_DEBUG
95 rdmc_warnprintf("DEBUG: could not open %s (zipped=%i)",name, zipped);
96#endif
97 return (NULL);
98 } /* if fopen == 0 */
99 } /* if name != "" */
100 else { /* no name --> stdin/out */
101 if (tolower((int) mode[0]) == 'w') /* I will write to stdout */
102 tf = stdout;
103 else { /* I will read from stdin (currently only *_ASCII_F) */
104 if (0
105#ifdef DUMAND_ASCII_F
106 || (format == DUMAND_ASCII_F)
107#endif
108#ifdef AMANDA_ASCII_F
109 || (format == AMANDA_ASCII_F)
110#endif
111#ifdef UWI_ASCII_F
112 || (format == UWI_ASCII_F)
113#endif
114 )
115 tf = stdin;
116 else {
117 free(fp);
118#ifdef RDMC_MCOPEN_DEBUG
119 rdmc_warnprintf("DEBUG: Unknown format %i to read from stdin", format);
120#endif
121 return(NULL);
122 } /* if no 'w' and no ASCII_F */
123 } /* in no 'w' */
124 } /* if name == "" */
125
126
127 /* before we can do something with the file
128 we need to track down the exact format for the ASCII format,
129 we try automatic detection in case of file-reading
130 dumand starts with "V"
131 while UWI starts with "F",
132 F2000 starts with "V 2000"
133 */
134 if (fmode == RDMC_READ_MODE){
135 if (0
136#ifdef DUMAND_ASCII_F
137 || (format == DUMAND_ASCII_F)
138#endif
139#ifdef UWI_ASCII_F
140 || (format == UWI_ASCII_F)
141#endif
142#ifdef AMANDA_ASCII_F
143 || (format == AMANDA_ASCII_F)
144#endif
145 ){
146 if (fgets(s,RDMC_MAXLINE,tf) == NULL) { /* try to read first line */
147 fclose(tf);
148 free(fp); /* free the memory */
149#ifdef RDMC_MCOPEN_DEBUG
150 rdmc_warnprintf("DEBUG: Cannot read first line");
151#endif
152 return NULL;
153 } else {
154 r=1;
155 /* ok we have the line in s and have to decode it now */
156#ifdef AMANDA_ASCII_F
157 if (r) {
158 rdmc_init_mcfile(fp,AMANDA_ASCII_F,fmode,tf);
159 r=rdmc_amanda_V(s,fp);
160 if(r == 0){
161 fp->format = AMANDA_ASCII_F;
162#if OLD
163 rdmc_push_line_buffer(&(fp->h_buff),s);
164#endif
165 fp->fpos++;
166 strncpy(fp->last_line,s,RDMC_MAXLINE-1);
167 fp->last_line[RDMC_MAXLINE]='\0';
168 fp->info.f2000.unread=1;
169 }
170 }
171#endif
172#ifdef DUMAND_ASCII_F
173 if (r) {
174 rdmc_init_mcfile(fp,DUMAND_ASCII_F,fmode,tf);
175 r= rdmc_a_V(s,fp);
176 if ( r == 0){ /* scan for version number */
177 fp->format = DUMAND_ASCII_F;
178 fp->fpos++;
179 strncpy(fp->last_line,s,RDMC_MAXLINE-1);
180 fp->last_line[RDMC_MAXLINE]='\0';
181 }
182 }
183#endif
184#ifdef UWI_ASCII_F
185 if (r) {
186 rdmc_init_mcfile(fp,UWI_ASCII_F,fmode,tf);
187 r = rdmc_uwi_FH(s,fp);
188 if ( r == 0){
189 fp->format = UWI_ASCII_F;
190 fp->fpos++;
191 strncpy(fp->last_line,s,RDMC_MAXLINE-1);
192 fp->last_line[RDMC_MAXLINE]='\0';
193 }
194 }
195#endif
196 if (r) { /* file could not be deytected */
197 fclose(tf);
198 free(fp); /* free the memory */
199#ifdef RDMC_MCOPEN_DEBUG
200 rdmc_warnprintf("DEBUG: Cannot recognize format of the following line:\n%s", s);
201#endif
202 return NULL;
203 }
204 }
205 } /* format defined */
206 else{ /* e.g. Baikal format */
207 rdmc_init_mcfile(fp,format,fmode,tf);
208 }
209 }else{ /* opened for writing */
210 rdmc_init_mcfile(fp,format,fmode,tf);
211 }/*atodetect in case of reading */
212
213 /* update the zip status */
214 fp->zipped=zipped;
215
216 if ((strstr(mode,"r") == NULL) && (strstr(mode,"a") == NULL))
217 return fp; /* only write mode: no test */
218
219 /* Now read the history and comment lines until the header starts */
220 switch(fp->format) {
221#ifdef UWI_ASCII_F
222 case UWI_ASCII_F:
223 r = rdmc_rhd_uwi(fp); /* read the UWI-like header */
224 break;
225#endif
226#ifdef DUMAND_ASCII_F
227 case DUMAND_ASCII_F:
228 r = rdmc_rhd_ascii(fp); /* read the dumand-like header */
229 break;
230#endif
231#ifdef AMANDA_ASCII_F
232 case AMANDA_ASCII_F:
233 r = rdmc_rhd_amanda(fp); /* read the amanda-like header */
234 break;
235#endif
236#ifdef BAIKAL_BIN_F
237 case BAIKAL_BIN_F: /* for the binary format */
238 r = rdmc_rhd_baikal_mc(fp); /* read the baikal like header */
239 break;
240#endif
241 default:
242 r = RDMC_UNKNOWN_FORMAT;
243 } /* switch fp->format */
244
245 if (r != 0) { /* if header reading was not successfull */
246 free(fp); /* free the memory */
247#ifdef RDMC_MCOPEN_DEBUG
248 rdmc_warnprintf("DEBUG: Cannot read header (%i)",r);
249#endif
250 fp = NULL; /* and reset the pointer to NULL */
251 }
252
253 return (fp);
254
255} /* function rdmc_mcopen() */
256
257/****************************************************************************/
258/* mcclose() closes a mc/data file */
259/* usage is like fclose() */
260/****************************************************************************/
261
262int rdmc_mcclose(mcfile *fp)
263{
264 int c=1;
265
266#ifdef AMANDA_ASCII_F
267 /* write end of file mark */
268 if (fp->format == AMANDA_ASCII_F){
269 rdmc_wrend_amanda(fp);
270 }
271#endif
272
273 /* close the file */
274 if (fp->zipped == 0)
275 c = fclose(fp->fp);
276 else
277// c = pclose(fp->fp);
278
279 rdmc_free_mcfile(fp); /* free/unallocate file structure */
280
281 return(c);
282
283} /* function mcclose() */
284
285
286/*****************************************************************************/
287/* rdmc_myopen() opens a file, maybe zipped. It returns the file pointer and */
288/* a flag if it has opened a pipe */
289/*****************************************************************************/
290FILE *rdmc_myopen(const char *name, const char *mode, int *piped)
291{
292 typedef FILE*(fopen_like_t)(const char *name, const char *mode);
293 struct open_table_s {
294 char *suffix;
295 fopen_like_t *open_function;
296 } open_table[] = {
297 {".gz", rdmc_gzipopen},
298 {"-gz", rdmc_gzipopen},
299 {".GZ", rdmc_gzipopen},
300 {"-GZ", rdmc_gzipopen},
301 {".bz", rdmc_bzipopen},
302 {"-bz", rdmc_bzipopen},
303 {".bz2", rdmc_bzip2open},
304 {"-bz2", rdmc_bzip2open},
305 {NULL, NULL}
306 };
307 struct open_table_s *entry;
308 char *r;
309
310 for (entry = open_table; entry->suffix != NULL; entry++)
311 if (rdmc_strsuf(name,entry->suffix)) {
312 *piped = 1;
313// return entry->open_function(name,mode);
314 }
315
316 if ((r = rdmc_remote_pipe(name, mode))) {
317 *piped = 1;
318// return popen(r, mode);
319 } /* if file name */
320
321 *piped = 0;
322 return fopen(name, mode); /* default: normal open */
323
324} /* rdmc_myopen() */
325
326/*****************************************************************************/
327/* strsuffix() tests if suf is a file suffix of str */
328/*****************************************************************************/
329int rdmc_strsuf(const char *str, const char *suf)
330{
331 const char *str_c, *suf_c;
332
333 if (strlen(suf) > strlen(str))
334 return 0;
335 for (str_c = str+strlen(str), suf_c = suf+strlen(suf);
336 (suf_c >= suf) && (str_c >= str);
337 str_c--, suf_c--)
338 if (*suf_c != *str_c) return 0;
339
340 return 1;
341
342} /* strsuffix() */
343
344/*****************************************************************************/
345/* gzipopen() opens a gzipped file for reading or writing (no seek!) */
346/* the file can be used with the usual fprintf()..pclose() functions */
347/* the function needs the gzip program to work, and will not work under */
348/* MS-DOS o.a. */
349/*****************************************************************************/
350
351FILE *rdmc_gzipopen(const char *name, const char *mode)
352{
353 char command[RDMC_MAXLINE];
354 char *r;
355
356 r = rdmc_remote_pipe(name, mode);
357 if (strchr(mode,'w')) { /* if there was a 'w' in the mode string */
358 if (r)
359 sprintf(command, "gzip | %s", r);
360 else
361 sprintf(command, "gzip > %s", name);
362// return popen(command,"w");
363 }
364 if (strchr(mode,'r')) { /* but if there was an 'r' */
365 if (r)
366 sprintf(command, "%s | gzip -dc", r);
367 else
368 sprintf(command, "gzip -dc %s", name);
369// return popen(command,"r");
370 }
371
372 return NULL;
373
374} /* rdmc_gzipopen() */
375
376/*****************************************************************************/
377/* bzipopen() opens a zipped file for reading or writing (no seek!) */
378/* the file can be used with the usual fprintf()..pclose() functions */
379/* the function needs the bzip program to work, and will not work under */
380/* MS-DOS o.a. */
381/*****************************************************************************/
382
383FILE *rdmc_bzipopen(const char *name, const char *mode)
384{
385 char command[RDMC_MAXLINE];
386 char *r;
387
388 r = rdmc_remote_pipe(name, mode);
389 if (strchr(mode,'w')) { /* if there was a 'w' in the mode string */
390 if (r)
391 sprintf(command, "bzip | %s", r);
392 else
393 sprintf(command, "bzip > %s", name);
394// return popen(command,"w");
395 }
396 if (strchr(mode,'r')) { /* but if there was an 'r' */
397 if (r)
398 sprintf(command, "%s | bzip -dc", r);
399 else
400 sprintf(command, "bzip -dc %s", name);
401// return popen(command,"r");
402 }
403
404 return NULL;
405
406} /* bzipopen() */
407
408/*****************************************************************************/
409/* bzip2open() opens a zipped file for reading or writing (no seek!) */
410/* the file can be used with the usual fprintf()..pclose() functions */
411/* the function needs the bzip2 program to work, and will not work under */
412/* MS-DOS o.a. */
413/* (bzip2 is a replacement for bzip with better+faster compression and */
414/* without patent problems) */
415/*****************************************************************************/
416
417FILE *rdmc_bzip2open(const char *name, const char *mode)
418{
419 char command[RDMC_MAXLINE];
420 char *r;
421
422 r = rdmc_remote_pipe(name, mode);
423 if (strchr(mode,'w')) { /* if there was a 'w' in the mode string */
424 if (r)
425 sprintf(command, "bzip2 | %s", r);
426 else
427 sprintf(command, "bzip2 > %s", name);
428// return popen(command,"w");
429 }
430 if (strchr(mode,'r')) { /* but if there was an 'r' */
431 if (r)
432 sprintf(command, "%s | bzip2 -dc", r);
433 else
434 sprintf(command, "bzip2 -dc %s", name);
435// return popen(command,"r");
436 }
437
438 return NULL;
439
440} /* bzip2open() */
441
442/*
443 * is_in_path() checks if a certain program can be found in the path.
444 * return value is the full path (with program name), or NULL
445 */
446char *rdmc_is_in_path(const char *program)
447{
448 char *path ,*p1;
449 static char *p=NULL;
450 static char progpath[RDMC_MAXLINE];
451 struct stat statbuf;
452
453 path = getenv("PATH");
454#ifndef CRAY
455 p = alloca(strlen(path)+1);
456#else
457 p = realloc(p,strlen(path)+1);
458#endif
459 strcpy(p, path);
460
461 for (p1 = strtok(p,":"); p1 != NULL; p1 = strtok(NULL,":")) {
462 sprintf(progpath,"%s/%s",p1,program);
463 if (!stat(progpath, &statbuf)) return progpath;
464 } /* for p1 */
465
466 return NULL;
467
468} /* is_in_path() */
469
470/*
471 * remote_pipe() builds the part of a pipe command for
472 * remote file opening.
473 * Just add this string to the beginning or end of your openng command.
474 * Actually, it looks just for a ':' in the file
475 * name and interprets the part before it as host (to be reached via RSH_CMD)
476 * if no remote part is found, NULL will be returned.
477 */
478
479char *rdmc_remote_pipe(const char *name, const char *mode)
480{
481#ifdef ALLOW_REMOTE
482 static char command[RDMC_MAXLINE];
483 char host[RDMC_MAXLINE];
484 char *file;
485 static char *rsh_cmd = NULL;
486
487 file = strchr(name,':');
488 if (file == NULL) return NULL;
489
490 if (!rsh_cmd) { /* init rsh command */
491 rsh_cmd = getenv(RSH_CMD_ENV);
492 if (!rsh_cmd) {
493 if (rdmc_is_in_path("ssh"))
494 rsh_cmd = "ssh";
495 else if (rdmc_is_in_path("rsh"))
496 rsh_cmd = "rsh";
497 else if (rdmc_is_in_path("remsh"))
498 rsh_cmd = "remsh";
499 else rsh_cmd = NULL;
500 }
501 }
502 if (!rsh_cmd) return NULL;
503
504 strncpy(host, name, file-name);
505 if (strchr(mode,'r')) /* but if there was an 'r' */
506 sprintf(command, "%s %s cat %s",
507 rsh_cmd, host, file+1);
508 else if (strchr(mode,'w')) /* if there was a 'w' in the mode string */
509 sprintf(command, "%s %s \"cat > %s\"",
510 rsh_cmd, host, file+1);
511 else return NULL;
512 return command;
513#else
514 return NULL
515#endif
516
517} /* remote_pipe() */