📄 find_data.c
字号:
/*===========================================================================*//* DMC Interim out | find_data.c | Scan_phase *//*===========================================================================*//* Name: find_data.c Purpose:to find all data records in the specified file which lie in whole or in part within the given time bounds and to create a list of file offset pointers to the beginnings of each continuous time segment formed by these records. Usage: int find_data () struct DMC_request req struct lvol **head struct lvol **tail struct path_list **data int *count struct lvol **first int err err = find_data (req, end_tspan, head, tail, data, count, first) Input: struct DMC_request req request file entry struct input_time end_tspan time of the current tspan end struct lvol **head ptr to ptr to head item in lvol list struct lvol **tail ptr to ptr to tail item in lvol list struct path_list **ptr ptr to ptr to circular list of data directory paths Output: struct lvol **tail ptr to ptr to tail item in lvol list struct path_list **ptr ptr to ptr to circular list of data directory paths int *count count of items added to lvol list struct lvol **first ptr to ptr to first item added to lvol list int find_data () = 0, normal = 1, file not found = 2, file open/status error = 3, file read error = 4, malloc error Externals: Debug - setting of environment variable DEBUG (globals.h) Messages: Warnings: Errors: Fatals: Called by: Calls to: find_name find absolute data file name and validate fileno return file descriptor for file ptr asc_to_input_time convert time structure cmp_time compare times find_segment find next continuous time segment in file put_lvol create an lvol list entry for a time segment Algorithm: Notes: none Problems: none known Debug: level D_MIN - print out start and finish notices level D_MED - print out actual file name and number of level D_MAX - References: none Language: ANSI standard C, under Sun OS 3.5 EXCEPT calls to "open" and "close" include file <sys/file.h> Revisions: 03/06/89 Kevin MacKenzie original version 10jul90 mw bugfix: need to be able to tell get_scaninfo what the end time of current tspan is, for zero sample interval data. 19mar91 mw bugfix if we take the "no data in requested time window" exit, previously the open file would remain open. (A good argument against having multiple exits!) The file is now closed before return. The symptoms were an eventual failure due to no more file descriptors available (too many open files errno=24). 17jun91 mw change check the offsets returned by find_segment just in case. xxyyy91 ss bugfix (sue shoch) 03dec91 mw bugfix find_segment can legitimately fail to set start_o and end_o - preset them before the call to find_segment so incorrect error msgs are not printed out. Thanks, Sue! Note that it could still fail on an empty file, but these files should not be empty anyway!*/ /*=====================================*//*=================| |=================*/ /*=====================================*/#include <stdio.h>#include <errno.h>#include "output.h"#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/param.h>#ifdef SOLARIS#include <fcntl.h>#endif/* ---------------------------------------------------------------------------- */extern int Write_Data;extern int Process_location_code;extern int PodJustDoIt;static char name[MAXPATHLEN + 1]; /* working file path name */static char prev_name[MAXPATHLEN + 1]; /* working file path name */static FILE *fptr;static struct stat stbuf; /* file status stuff *//* --------------------------------------------------------------------------- */void init_find_data(){ strcpy(name, ""); strcpy(prev_name, ""); fptr = NULL;}/* --------------------------------------------------------------------------- */int find_data (req, end_tspan, head, tail, data, count, first)struct DMC_request *req; /* request file entry */ struct input_time end_tspan; /* current tspan end time */struct lvol **head; /* ptr to head item in lvol list */struct lvol **tail; /* ptr to tail item in lvol list */struct path_list **data; /* ptr to ptr to circular list of data */ /* directory paths */int *count; /* ptr to count of items added to lvol */struct lvol **first; /* ptr to ptr to first item added to */ /* lvol list */{ int err; /* result */ struct lvol *ptail; /* ptr to tail of lvol at entry */ int n; /* number of segments in input file */ struct input_time fstart; /* input file start time */ struct input_time fend; /* input file end time */ int flen; /* input file length in bytes */ struct input_time start; /* requested data window start time */ struct input_time end; /* requested data window end time */ struct input_scan scan; /* hdr info for current time segment */ int start_o; /* fseek start offset of time segment */ int end_o; /* fseek end offset of time segment */ struct input_time endtime; /* found end time */ char msg[100]; /* error message text */ char *p; int default_lrecl; if (!Write_Data) { *count = 0; *first = NULL; /* no first lvol entry */ /* create dummy structs */ memset(&scan, 0, sizeof(struct input_scan)); memset(&start, 0, sizeof(struct input_time)); memset(&end, 0, sizeof(struct input_time)); memcpy(scan.station, req->entry.statn, sizeof(scan.station)); /* network */ strcpy(scan.network, req->entry.network); if (Process_location_code) strcpy(scan.location, req->entry.location); memcpy(scan.channel, req->entry.chn, sizeof(scan.channel)); scan.time = asc_to_input_time(req->entry.start); end = asc_to_input_time(req->entry.end); err = 0; if (put_lvol (head,tail, &scan, "", &end, 0, 0) == 0) { /* count the new node */ (*count)++; if (*first == NULL) /* save ptr to first entry*/ *first = *tail; } else { err = 4; /* malloc error */ } return(err); } if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Started.\n"); *count = 0; *first = NULL; /* no first lvol entry */#if 0 if (PodJustDoIt) strcpy(name, req->entry.file); else if ((err = find_name (req, data, name)) != 0) { sprintf( msg, "[find_data] can't find data file %s code %d\n", req->entry.file, err ); perror("pod"); (void)error_handler( ERROR, msg ); if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Finished.\n"); return (err); /* file not found or abnormal */ }#endif if (Debug >= D_MED) fprintf (D_OUT, "[find_data] Absolute file path name = %s\n",name); /* open the extant file */ if (strcmp(prev_name, req->entry.file) != 0) { if ((err = find_name (req, data, name)) != 0) { sprintf( msg, "[find_data] can't find data file %s code %d\n", req->entry.file, err ); perror("pod"); (void)error_handler( ERROR, msg ); strcpy(prev_name, ""); if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Finished.\n"); return (err); /* file not found or abnormal */ } if (fptr != NULL) fclose(fptr); if ((fptr = fopen (name, "r")) == (FILE *)NULL) { sprintf( msg, "[find_data] can't open data file %s\n", name ); (void)error_handler(ERROR, msg); perror("pod; find_data()"); if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Finished.\n"); /* avoid the error of coming back with a null file pointer * but with the above strcmp resulting in true */ strcpy(prev_name, ""); /* file open error */ return (err = 2); } strcpy(prev_name, req->entry.file); if(stat(name, &stbuf ) < 0 ) { (void)error_handler( FATAL,"[find_data] fstat failed." ); } }#if 0 if(stat(name, &stbuf ) < 0 ) { (void)error_handler( FATAL,"[find_data] fstat failed." ); }#endif rewind(fptr); /* get info from request entry */ n = 0; /* always assume we don't know how many segments there are */ fstart = asc_to_input_time (req->entry.start);/* file start time */ fend = asc_to_input_time (req->entry.end); /* file end time */ flen = (int)stbuf.st_size; /* actual size of file */ start = asc_to_input_time (req->reqstart); /* request start time */ end = asc_to_input_time (req->reqend); /* request end time */ if (cmp_time (fend, start, 1) == -1 || cmp_time (end, fstart, 1) == -1) { /* return if entire file outside time window */ fprintf (D_OUT, "[find_data] No data in data file (from hfile) for requested time window.\n"); fprintf (D_OUT, "[find_data] Data file = %s\n", name); /* fclose(fptr); */ if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Finished.\n"); return (err = 0); } /* handy flag in find_segment which turns on and off the printing * out of non-blank location code warning. Reset outside of "do" loop. */ set_msg_printed_flag(0); /* fetch pointers to each continuous time segment * lying in requested window */ default_lrecl = Lrecl; Lrecl = find_Lrecl(fptr, name); /* if data record length is greater then the logical record length, * print error message. */ if (Lrecl > default_lrecl) { sprintf(msg, "[find_data] Logical record length is smaller than the data record length"); (void)error_handler(FATAL, msg); exit(-1); } do { /* scan for next continuous time segment */ start_o = 0; /* in case find_segment fails, don't */ end_o = 1; /* print incorrect warnings */ if (Debug >= D_MIN) fprintf (D_OUT, "start_o = %d end_o = %d\n", start_o, end_o); err = find_segment (name, fptr, &start, &end, n, &fend, flen, &end_tspan, &scan, &endtime, &start_o, &end_o, fptr); if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] err from find_seg = %d\n", err ); if( end_o <= start_o || start_o < 0 || end_o < 0 || start_o > (int)stbuf.st_size || end_o > (int)stbuf.st_size ) { if (Debug >= D_MIN) fprintf (D_OUT, "start_o = %d end_o = %d\n", start_o, end_o); sprintf( msg, "[find_data] bad data pointers in find_segment: %d to %d", start_o, end_o ); (void)error_handler( ERROR, msg ); } if (err < 2) { /* found a time segment; add node to lvol */ if (put_lvol(head,tail, &scan,name,&endtime, start_o,end_o) == 0) { (*count)++; /* count the new node */ if (*first == NULL) *first = *tail; /* save ptr to first entry*/ } else { err = 4; /* malloc error */ } } } while (err < 1);/* quit after last segment, eof, or error */ /* Always reset it as it is set in find_segment */ Lrecl = default_lrecl; /* close file and return */ /* fclose(fptr); */ if (Debug >= D_MED) fprintf (D_OUT, "[find_data] Nodes added to lvol = %d\n",*count); if (Debug >= D_MIN) fprintf (D_OUT, "[find_data] Finished.\n"); return (err = (err < 3) ? 0 : err);}/* ----------------------------------------------------------------------- *//* ------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -