/* * =========== FILE: getfilename.c =========== * * Description -- This routine returns data file names based upon the requested * time range in the local database. * * Synopsis -- int get_file_name (data_key, btime, etime, type, exten, fname) * * SDDAS_LONG data_key * Time_t btime, etime; * RequestedDataType type; * char *exten, *fname; * * data_key the data_key for project/mission/experiment/instrument/virtual * btime the start time requested * etime the stop time requested * type file type: header, data, vidf * exten filename extension for the data to be used * fname returned path and file of requestd data * * Return Values -- * * Fatal errors: * DBF_OPEN_ERROR - can't open the databases * DBF_READ_ERROR - can't read the databases * CONFIG_FILE_ERROR - can't read the config file or * find what I am looking for in then * * Nonfatal error: * NO_DATA - can't find the requested data in the database * * Ok return value: * ALL_OK - the data was found in the database * * Routines Used -- * * int find_entry() finds all database entries that cover the input time range * int OpenDbf() open a database file and initialize structure * int OpenIndex() open an index file * FieldRecord_t *FIELD() return a pointer to a field within a database record * * Externals -- * * dbfRecords_t *dbfRecords database structures * LinkList Projects pointer to projects tree * * Internals -- * * StrHier I, V pointers to the instrument and virtual * instrument data within the project tree * Time_t r_btime begin time of in database record * Time_t r_btime end time of in database record * int first flag to indicate the first file found for the time range * char str[10] string to aid in converting the time from thedatabase file * char *r_fname file name from database record * char *file[30] found data file to return * char vname[10] virtual instrument for database record * char *r_vname trimmed virtual instrument name * char *path path value from configuration file */ #include /* for assert */ #include /* for memset */ #include "ant.h" /* for GetHomeDirectory */ #include "SDDAS_types.h" #include "dbf.h" #include "DbDefs.h" #include "libCfg.h" #include "libserver.h" #include "local.h" #define FG(a,b,c) if (FieldGetN(a, b, c) != SUCCESS) return DBF_READ_ERROR SDDAS_INT get_file_name (SDDAS_ULONG data_key, Time_t *btime, Time_t etime, RequestedDataType type, const char *exten, SDDAS_CHAR *fname) { SDDAS_CHAR file [30], *r_fname; SDDAS_CHAR *path, DbfName [FILE_NAME_LEN], NdxName [FILE_NAME_LEN]; SDDAS_INT Dbf, Ndx; Time_t r_btime; StrHier src; SDDAS_SHORT params[5]; key_to_fields (data_key, params); src = SourceByNum (Projects, params[0], params[1], params[2], params[3], params[4], NULL); /* debug (3, "Src: %s, Type: %d\n", src->str, type); debug (3, "BT: %4d/%03d %d\n", btime.yr, btime.day, btime.msec); debug (3, "ET: %4d/%03d %d\n", etime.yr, etime.day, etime.msec); */ /* * if we're looking for real-time data then use the correct paths and * file names */ if (btime->yr == -1 || btime->yr == -2) { if ((path = CfgPath (src, "RealTimePath", 4)) == NULL) { return CONFIG_FILE_ERROR; } switch (type) { case _HEADER_: sprintf (fname, "%s/%sH", path, StrHierName (src)); break; case _DATA_: sprintf (fname, "%s/%sD", path, StrHierName (src)); break; case _VIDF_: sprintf (fname, "%s/%sI", path, StrHierName (src)); break; case _H_AND_D_: assert (type != _H_AND_D_); } /* switch */ return ALL_OK; } /* * the request is for post-time data, need to open the database to search * for the correct file that contains the request time and decoded key */ /* * get the database directory path and generate the database and index * filenames */ if ((path = DbfFile (src)) == NULL) return CONFIG_FILE_ERROR; memset (DbfName, 0, sizeof (DbfName)); memset (NdxName, 0, sizeof (NdxName)); switch (type) { case _H_AND_D_: case _HEADER_: case _DATA_: sprintf (DbfName, "%s.HD.DBF", path); sprintf (NdxName, "%s.HD.NDX", path); break; case _VIDF_: sprintf (DbfName, "%s.I.DBF", path); sprintf (NdxName, "%s.I.NDX", path); break; } /* switch */ /* open up the database and index files */ if (OpenDbf (&Dbf, DbfName, O_RDONLY) != SUCCESS) { return DBF_OPEN_ERROR; } if (OpenNdx (Dbf, NdxName, &Ndx) != SUCCESS) { CloseDbf (Dbf); return DBF_OPEN_ERROR; } /* perform a search for the requested data, if not found return NO_DATA */ if (!find_entry (Dbf, Ndx, StrHierName (src), *btime, etime, 1)) { CloseNdx (Dbf, Ndx); CloseDbf (Dbf); return NO_DATA; } /* We found the data we are looking for in the database, so lets build a filename and change the beginning time to be based on what is found in the database */ /* pull the beginning time from the current database record */ FG (Dbf, "B_YR", &(r_btime.yr)); FG (Dbf, "B_DAY", &(r_btime.day)); FG (Dbf, "B_MSEC", &(r_btime.msec)); /* Make the file name */ switch (type) { case _HEADER_ : sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'H')); break; case _DATA_ : sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'D')); break; case _VIDF_ : sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'I')); break; case _H_AND_D_: assert (type != _H_AND_D_); } /* switch */ r_fname = rtrim (file); /* * if the exten variable has something in it, use the user data * path for data instead of the default one */ if (strlen (exten) != 0) { if (getenv ("USER_DATA") == NULL) { char *tmp = GetHomeDirectory (); if (tmp != NULL) sprintf (fname, "%s/%s%s", tmp, r_fname, exten); } else { sprintf (fname, "%s/%s%s", getenv ("USER_DATA"), r_fname, exten); } } else { sprintf (fname, "%s/%s", CfgPath (src, "PostTimePath", 4), r_fname); } /* * Check the times of the returned entry. If the time range requested falls * into a different time span of a data file, change the requested time to * match what we have in the data base. The reason for this is so time for * any future files (i.e. VIDF file) will match the database exactly. For * example, if the data file you need requires a different VIDF file than * the one used for a previous data file, then you can get at the correct * VIDF without knowing that you switched VIDF files. */ if (r_btime.yr != btime->yr) { btime->yr = r_btime.yr; btime->day = r_btime.day; btime->msec = r_btime.msec; } else if ((r_btime.yr == btime->yr) && (r_btime.day != btime->day)) { btime->day = r_btime.day; btime->msec = r_btime.msec; } else if ((r_btime.yr == btime->yr) && (r_btime.day == btime->day) && (r_btime.msec != btime->msec)) btime->msec = r_btime.msec; /* Close out databases and then return ALL_OK. */ CloseNdx (Dbf, Ndx); CloseDbf (Dbf); return ALL_OK; #if 0 /************************** ALL THIS IS IGNORED! *****************************/ /* We took this out because we had no idea what purpose it served. We are leaving it in incase it ever becomes useful again. - JM */ /* pull the beginning time from the current database record */ FG (Dbf, "B_YR", &(r_btime.yr)); FG (Dbf, "B_DAY", &(r_btime.day)); FG (Dbf, "B_MSEC", &(r_btime.msec)); /* * loop to make sure we get all the data requested and it's online, ready * to use */ if (r_btime.msec > btime->msec) btime->msec = r_btime.msec; first = 1; do { /* pull the ending time from the database record */ FG (Dbf, "E_YR", &(r_etime.yr)); FG (Dbf, "E_DAY", &(r_etime.day)); FG (Dbf, "E_MSEC", &(r_etime.msec)); if (first) { switch (type) { case _HEADER_: sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'H')); break; case _DATA_: sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'D')); break; case _VIDF_: sprintf (file, "%s", SwRI_MakeFileName (StrHierName (src), r_btime, 'I')); break; case _H_AND_D_: assert (type != _H_AND_D_); } /* switch */ r_fname = rtrim (file); /* * if the exten variable has something in it, use the user data * path for data insted of the default one */ if (strlen (exten) != 0) { if (getenv ("USER_DATA") == NULL) { char *tmp = GetHomeDirectory (); if (tmp != NULL) sprintf (fname, "%s/%s%s", tmp, r_fname, exten); } else { sprintf (fname, "%s/%s%s", getenv ("USER_DATA"), r_fname, exten); } } else { sprintf (fname, "%s/%s", CfgPath (src, "PostTimePath", 4), r_fname); } /* * is this entry online ?? */ if (online (fname)) { /* * only want the first file name to pass back */ first = 0; break; } } /* * adjust the begin time to check to see if the next record is also * within the requeted time range */ btime->msec = r_btime.msec; btime->day = r_btime.day; btime->yr = r_btime.yr; btime->msec += 1000; /* * get the next record in line */ if (Skip (Dbf, Ndx, 1) != SUCCESS) { break; } /* * get the virtual instrument name, check to see if we're still in * the correct virtual instrument list */ FG (Dbf, "V_INST", vname); FG (Dbf, "B_YR", &(r_btime.yr)); FG (Dbf, "B_DAY", &(r_btime.day)); FG (Dbf, "B_MSEC", &(r_btime.msec)); r_vname = rtrim (vname); if (!r_vname) r_vname = vname; } while (strcmp (r_vname, StrHierName (src)) == 0 && compare_times (r_btime, etime) <= 0); /* * we're all done - close the database files */ CloseNdx (Dbf, Ndx); CloseDbf (Dbf); return ALL_OK; if (first == 0) { /* * found a file to plot */ /* debug (3, "fname: %s\n", fname); */ return ALL_OK; } else { return NO_DATA; } /************************** ALL THIS IS IGNORED! *****************************/ #endif }