/****************************************************************************/ /* Copyright 1997 MBARI */ /****************************************************************************/ /* $Header: argfile.c,v 3.2 2001/06/19 13:00:36 oasisa Exp $ */ /* Summary : File Handling Routines for `extract` */ /* Filename : file.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 3.2 $ */ /* Created : 02/05/91 */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 13jan97 rah - created from file.c */ /* $Log: argfile.c,v $ * Revision 3.2 2001/06/19 13:00:36 13:00:36 oasisa (Oasis users) * Periodic Update w/ changes to utils * plus new utils 6/19/2001 (klh) * * Revision 3.0 99/05/12 10:11:31 10:11:31 bobh (Bob Herlien) * Added tstring, misc changes * * Revision 2.9 98/08/24 13:45:59 13:45:59 bobh (Bob Herlien) * Archiving sources after M2/M3 & Eqpac deployments of 1998 * * Revision 2.8 98/03/17 11:11:46 11:11:46 bobh (Bob Herlien) * Archiving sources prior to porting to DOS/Windows * * Revision 1.1 97/10/27 09:53:19 09:53:19 bobh (Bob Herlien) * Initial revision * */ /****************************************************************************/ #include /* Standard I/O */ #include /* Standard library functions */ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* Time */ #include /* for isspace() */ #include /* for strcmp() */ #include /* variable argument lists */ #include /* ARGOS buffer definitions */ #include /* memory allocation */ #define LINEBUFSIZE 1024 /* Size of line buffer */ #define BNAMESIZE 64 /* Size of file base name */ #define NAMESIZE 256 /* Space allocated for file names */ #define BASE_DIR "/oasis/eqpac" #define CFG_DIR "/oasis/eqpac/cfg" #define GMT_OFFSET (-8) typedef struct /************************************/ { /* FilePtr struct - File Ptr and name*/ FILE *fp; /* File pointer */ char *fname; /* File base name */ } FilePtr; /************************************/ typedef struct /************************************/ { /* CalStruct - Funcs to read cal files*/ char *cs_name; /* Keyword in cfg file */ Status (*cs_func)(); /* Function to read cal file */ Void *cs_parm; /* Ptr parm to pass to cs_func */ } CalStruct; /************************************/ /********************************/ /* External Functions */ /********************************/ Extern Status read_spec_cal( char *name, SpecCal *scp ); /********************************/ /* Forward Declarations */ /********************************/ Status store_dirname( char *name, char *where ); Status store_fname( char *name, char **where ); Status analog_cal( char *parm, Analog *cp, char *tail ); Status setInt32( char *value, Int32 *where ); Status setMBool( char *value, MBool *where ); /********************************/ /* Global Data */ /********************************/ Global MBool smallConfig = FALSE; Global MBool reverseNO3 = FALSE; Global Int32 gmt_offset = GMT_OFFSET; Global Nat32 temp_offset = 380; Global Int32 revision = DFLT_REV; /* Software & msg type revision nmbr*/ Global char can_name[BNAMESIZE]; /* Name of OASIS can */ Global Analog analog[ANALOG_CHANS]; /* Analog calibration */ Global SpecCal spec_cal; /* Struct to hold Spect calibrations*/ /********************************/ /* Module Local Data */ /********************************/ MLocal char base_dir[NAMESIZE]; /* Name of base dir for output data */ MLocal char cfg_file[NAMESIZE]; /* Name of OASIS configuration file */ MLocal char line_buf[LINEBUFSIZE]; /* Place to scan line input */ /* File ptrs and names for outputs */ MLocal FilePtr files[] = { {NULLF, "error"}, {NULLF, "co2"}, {NULLF, "co2.cal"}, {NULLF, "no3.0m"}, {NULLF, "no3.20m"}, {NULLF, "spec.noon"}, {NULLF, "spec.1030"}, {NULLF, "spec.20m"}, {NULLF, "mcp"}, {NULLF, "ac9.1"}, {NULLF, "ac9.2"}, {NULLF, "temp.0m"}, {NULLF, "temp.20m"}, {NULLF, "oasis"}, {NULLF, "argos"}, {NULLF, "spec.0m.1230"}, {NULLF, "spec.20m.1230"}, {NULLF, "spec.0m.dark"}, {NULLF, "spec.20m.dark"}, {NULLF, "wetstar"}, {NULLF, "shutter"}, {NULLF, "sat1.dark"}, {NULLF, "sat1"}, {NULLF, "spec.misc"}, {NULLF, "spec.0m.1000"},{NULLF, "spec.20m.1000"},{NULLF, "isus"},{NULLF, "hs2"} }; MLocal CalStruct cals[] = /* File funcs and names for calibr */ { { "errors", store_fname, (Void *)&(files[ERROR_FILE].fname) }, { "data", store_dirname, (Void *)base_dir }, { "analog", analog_cal, (Void *)analog }, { "shortdata", setMBool, (Void *)&smallConfig }, { "revision", setInt32, (Void *)&revision }, { "gmtoffset", setInt32, (Void *)&gmt_offset }, { "tempoffset", setInt32, (Void *)&temp_offset }, { "reverseNO3", setMBool, (Void *)&reverseNO3 }, { "specprr", read_spec_cal, (Void *)&spec_cal } }; /************************************************************************/ /* Function : get_sensor_file */ /* Purpose : Get file pointer for given sensor */ /* Inputs : Sensor */ /* Outputs : None */ /************************************************************************/ FILE * get_sensor_file( Int sensor ) { FILE *fp; if ( (fp = files[sensor].fp) != NULLF ) return( fp ); if ( files[sensor].fname[0] == '/' ) strcpy( line_buf, files[sensor].fname ); else sprintf( line_buf, "%s/%s", base_dir, files[sensor].fname ); if ( (fp = fopen(line_buf, "a")) == NULLF ) { if ( sensor == ERROR_FILE ) fp = stderr; fprintf( files[ERROR_FILE].fp, "Cannot open %s\n", line_buf ); } files[sensor].fp = fp; return( fp ); } /* get_sensor_file() */ /************************************************************************/ /* Function : close_sensor_files */ /* Purpose : Close all output files for sensors */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void close_sensor_files( Void ) { Int i; for ( i = 0; i < ARGFILES; i++ ) if ( files[i].fp != NULLF ) { fclose( files[i].fp ); files[i].fp = NULLF; } } /* close_sensor_files() */ /************************************************************************/ /* Function : print_error */ /* Purpose : Print error message to error file */ /* Inputs : Format string, arguments as in printf */ /* Outputs : None */ /************************************************************************/ Void print_error( char *fmt, ... ) { va_list ap; /* Argument pointer */ FILE *fp; /* Error file pointer */ va_start( ap, fmt ); if ( (fp = get_sensor_file(ERROR_FILE)) == NULLF ) fp = stderr; vfprintf( fp, fmt, ap ); va_end( ap ); } /* print_error() */ /************************************************************************/ /* Function : print_sensor */ /* Purpose : Print to sensor file */ /* Inputs : Sensor, format string, arguments as in printf */ /* Outputs : None */ /************************************************************************/ Void print_sensor( Int sensor, char *fmt, ... ) { va_list ap; /* Argument pointer */ FILE *fp; /* Error file pointer */ va_start( ap, fmt ); if ( (fp = get_sensor_file(sensor)) != NULLF ) vfprintf( fp, fmt, ap ); va_end( ap ); } /* print_sensor() */ /************************************************************************/ /* Function : store_dirname */ /* Purpose : Store a directory name in local static data */ /* Inputs : Where to store name, name to store */ /* Outputs : OK */ /************************************************************************/ Status store_dirname( char *name, char *where ) { strncpy( where, name, BNAMESIZE ); return( OK ); } /* store_dirname() */ /************************************************************************/ /* Function : store_fname */ /* Purpose : Allocate space and store a file name */ /* Inputs : Name to store, where to put new pointer */ /* Outputs : OK or ERROR */ /************************************************************************/ Status store_fname( char *name, char **where ) { Reg char *p; if ( (p = (char *)malloc(strlen(name) + 1)) == NULL ) return( ERROR ); strcpy( p, name ); *where = p; return( OK ); } /* store_fname() */ /************************************************************************/ /* Function : analog_cal */ /* Purpose : Read analog calibration directly from cfg file */ /* Inputs : Dummy parameter, ptr to analog cal struct, ptr to tail */ /* Outputs : OK */ /************************************************************************/ Status analog_cal( char *parm, Analog *cp, char *tail ) { char unitname[UNITNAMELEN]; Int channel, i; double a, b, c, d; if ( (i = sscanf(tail, " %d %lf %lf %lf %lf %s", &channel, &a, &b, &c, &d, unitname)) >= 3 ) { analog[channel].a = a; analog[channel].b = b; analog[channel].c = c; analog[channel].d = d; if ( i >= 6 ) strncpy( analog[channel].units, unitname, UNITNAMELEN ); } return( OK ); } /* analog_cal() */ /************************************************************************/ /* Function : setMBool */ /* Purpose : Set a static MBool */ /* Inputs : ASCII value, Boolean to set */ /* Outputs : OK */ /************************************************************************/ Status setMBool( char *value, MBool *where ) { *where = atoi( value ); return( OK ); } /* setMBool() */ /************************************************************************/ /* Function : setInt32 */ /* Purpose : Store an integer */ /* Inputs : ASCII value, place to store it */ /* Outputs : OK */ /************************************************************************/ Status setInt32( char *value, Int32 *where ) { sscanf( value, " %d", where ); return( OK ); } /* setInt32() */ /************************************************************************/ /* Function : get_can_name */ /* Purpose : Get name of OASIS can, set base directory name */ /* Inputs : Name of data file */ /* Outputs : Ptr to Global variable can_name */ /* Side Effects: Fills in can_name with name of OASIS can */ /* Sets base and header directory names */ /* Sets name of OASIS data file, if necessary */ /************************************************************************/ Void get_can_name( char *dataname ) { Reg char *p, *q; Reg Nat32 i; if ( (p = strrchr(dataname, '/')) == NULL ) p = dataname; else p++; if ( (q = strchr(p, '.')) != NULL ) i = q - p; else i = strlen(p); strncpy( can_name, p, i ); can_name[i] = '\0'; sprintf( base_dir, "%s/%s", BASE_DIR, can_name ); } /* get_can_name() */ /************************************************************************/ /* Function : read_cfg */ /* Purpose : Read OASIS configuration file */ /* Inputs : Ptr to cfg file name ptr */ /* Outputs : OK or ERROR */ /************************************************************************/ Status read_cfg( char **cfgname ) { Reg FILE *fp; Reg Nat32 i; Nat32 n; Reg char *p; char keywd_buf[NAMESIZE]; char name_buf[NAMESIZE]; memset( (void *)&spec_cal, sizeof(spec_cal), 0 ); memset( (void *)analog, sizeof(analog), 0 ); if ( *cfgname == NULL ) { sprintf( cfg_file, "%s/%s.cfg", CFG_DIR, can_name ); *cfgname = cfg_file; } if ( (fp = fopen(*cfgname, "rb")) == (FILE *)NULL ) return( ERROR ); memset( (void *)&analog, 0, ANALOG_CHANS * sizeof(Analog) ); while ( fgets(line_buf, sizeof(line_buf), fp) != NULL ) { /* Read one line of input*/ p = line_buf; if ( sscanf(p, " %s%n %s", keywd_buf, &n, name_buf) == 2 ) for ( i = 0; i < (sizeof(cals)/sizeof(CalStruct)); i++ ) if ( strcasecmp(keywd_buf, cals[i].cs_name) == 0 ) { if ( (*cals[i].cs_func)(name_buf, cals[i].cs_parm, p+n) != OK ) printf("Can't read calibration file %s\n", name_buf); break; } } fclose( fp ); return( OK ); } /* read_cfg() */ /************************************************************************/ /* Function : getIntelword */ /* Purpose : Get a word in Intel format from data stream */ /* Inputs : Ptr to data stream */ /* Outputs : Word */ /************************************************************************/ Nat16 getIntelword( Byte *p ) { Nat16 rtn; rtn = (Nat16)(*p); rtn += (Nat16)(p[1] << 8); return( rtn ); } /* getIntelword() */ /************************************************************************/ /* Function : getIntellong */ /* Purpose : Get a longword in Intel format from data stream */ /* Inputs : Ptr to data stream */ /* Outputs : Long */ /************************************************************************/ Nat32 getIntellong( Byte *p ) { Nat32 rtn; rtn = (Nat32)getIntelword(p); rtn += ((Nat32)getIntelword(&p[2]) << 16); return( rtn ); } /* getIntellong() */ /************************************************************************/ /* Function : getMotword */ /* Purpose : Get a word in Motorola format from data stream */ /* Inputs : Ptr to data stream */ /* Outputs : Word */ /************************************************************************/ Nat16 getMotword( Byte *p ) { Nat16 rtn; rtn = (Nat16)(*p << 8); rtn += (Nat16)(p[1]); return( rtn ); } /* getMotword() */