dtsrhan.c 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * COMPONENT_NAME: austext
  25. *
  26. * FUNCTIONS: cleanup
  27. * flag_shutdown
  28. * is_blank
  29. * is_count
  30. * is_time
  31. * is_whitespace
  32. * main
  33. * mmm_to_digits
  34. * my_strtok
  35. * new_rec
  36. * open_outfile
  37. * process_infile
  38. * process_profile
  39. * process_record
  40. * segregate_dicname
  41. * token
  42. * usage_msg
  43. * user_arg_processor
  44. * validate_id
  45. * write_record
  46. *
  47. * ORIGINS: 27
  48. *
  49. *
  50. * (C) COPYRIGHT International Business Machines Corp. 1993,1996
  51. * All Rights Reserved
  52. * Licensed Materials - Property of IBM
  53. * US Government Users Restricted Rights - Use, duplication or
  54. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  55. */
  56. /************** DTSRHAN.C ***************
  57. * $XConsortium: dtsrhan.c /main/9 1996/09/23 21:02:27 cde-ibm $
  58. * Oct 1993.
  59. * Modification of handel.c for CDE system.
  60. * Converts free form text in accordance with a profile file
  61. * into a formal .fzk file.
  62. *
  63. * $Log$
  64. * Revision 2.8 1996/04/10 22:55:27 miker
  65. * Removed ref to BETA.
  66. *
  67. * Revision 2.7 1996/04/10 19:48:52 miker
  68. * Added support for null dates.
  69. *
  70. * Revision 2.6 1996/03/25 18:53:56 miker
  71. * Changed FILENAME_MAX to _POSIX_PATH_MAX.
  72. *
  73. * Revision 2.5 1996/02/01 18:20:02 miker
  74. * Changed parser/stemmer calls to new readchar format.
  75. *
  76. * Revision 2.4 1995/11/07 17:51:46 miker
  77. * Fixed bug in progress dot processing.
  78. * Added rec count to err msgs to facilitate finding bad recs.
  79. *
  80. * Revision 2.3 1995/10/25 18:57:27 miker
  81. * Renamed from chandel.c. Added prolog.
  82. *
  83. * Log: chandel.c,v
  84. * Revision 2.2 1995/10/02 20:00:51 miker
  85. * Added semantic analysis so original handel.c no longer required.
  86. *
  87. * Revision 2.1 1995/09/22 19:20:45 miker
  88. * Freeze DtSearch 0.1, AusText 2.1.8
  89. *
  90. * Revision 1.7 1995/09/19 21:49:22 miker
  91. * ifdef DTSEARCH, use DtSrVERSION instead of AUSAPI_VERSION in banner.
  92. *
  93. * Revision 1.6 1995/08/31 22:15:33 miker
  94. * Added MMM fields for date processing like handel.c.
  95. * Minor changes for DtSearch, mostly msg sets changes..
  96. * Executable module renamed dtsrload for DtSearch.
  97. *
  98. * Revision 1.5 1995/06/08 00:32:43 miker
  99. * 2.1.5f: Bug fix. Segfault if constant string not enclosed in quotes.
  100. * Enable negative field offsets.
  101. */
  102. #include "SearchP.h"
  103. #include <limits.h>
  104. #include <string.h>
  105. #include <stdlib.h>
  106. #include <errno.h>
  107. #include <ctype.h>
  108. #include <signal.h>
  109. #include <time.h>
  110. #include <locale.h>
  111. char *strupr(char *); // lib/DtSearch/dtsrve.c
  112. #define PROGNAME "DTSRHAN"
  113. #define MS_chandel 5
  114. #define RECS_PER_DOT 10L
  115. /*-- Numerical codes for storing "undefined items" --*/
  116. #define UNDEFINED 0
  117. #define ANY -999
  118. /*-- Codes for "modes" of text buffering --*/
  119. #define INCLUDE 1
  120. #define EXCLUDE 2
  121. #define SET 3
  122. #define CLEAR 4
  123. #define DEFAULT 5
  124. #define NONE 6
  125. /*-- codes for abstract mode --*/
  126. #define FIELDS 2
  127. #define USER 3
  128. #define GENERATE 4
  129. /*-- Exit codes for errors --*/
  130. #define USAGE 2
  131. #define FILE_ERROR 3
  132. #define SYNTAX_ERROR 4
  133. #define BAD_ID 5
  134. #define BAD_DIC 6
  135. #define BAD_PROFILE 7
  136. #define CRIT 9
  137. /*-- Token types --*/
  138. #define UNKNOWN 999
  139. #define LINE 1
  140. #define FIELD 2
  141. #define TEXT 3
  142. /****#define WORDS 4*****/
  143. #define IMAGE 5
  144. #define KEY 6
  145. #define ABSTR 7
  146. #define KEYCHAR 8
  147. #define DELIMITER 9
  148. #define TEXTINCLUDE 10
  149. #define TEXTEXCLUDE 11
  150. #define TFIELDINCLUDE 12
  151. #define TFIELDEXCLUDE 13
  152. #define DELBLANKLINES 14
  153. #define IMAGEINCLUDE 15
  154. #define IMAGEEXCLUDE 16
  155. #define DISCARD 17
  156. #define CONSTANT 18
  157. #define UPPER 19
  158. #define DATEFLD 20
  159. /*-- General Defines --*/
  160. #define EOLN -999
  161. #define EOW -998
  162. #define CNTRL_L 12
  163. #define MAX_ALPHABET_SIZE 256
  164. /*-- definitions of various data structures --*/
  165. struct line_comp { /*-- Individual components for line ids --*/
  166. int column_number;
  167. char text[80];
  168. int d[MAX_ALPHABET_SIZE];
  169. int text_length;
  170. struct line_comp *next;
  171. };
  172. struct line_id { /*-- list of line ids to be handled --*/
  173. char name[80];
  174. struct line_comp *comp;
  175. struct line_comp *head;
  176. struct line_id *next;
  177. struct rec *line;
  178. int word_action;
  179. int text_action;
  180. int image_action;
  181. };
  182. struct field_id { /*-- list of field ids to be used --*/
  183. struct field_id *next;
  184. char name[80];
  185. struct line_id *line;
  186. int offset;
  187. int defined_length;
  188. int length;
  189. char text[80];
  190. int d[MAX_ALPHABET_SIZE];
  191. int text_length;
  192. char value[80];
  193. int word_action;
  194. int text_action;
  195. int image_action;
  196. char line_id[80];
  197. int constant;
  198. int is_month;
  199. };
  200. struct rec { /*-- holds a complete image of a record --*/
  201. struct rec *next;
  202. struct line_id *line;
  203. int line_num;
  204. char text[200];
  205. };
  206. struct date_id {
  207. char field_id[80];
  208. struct date_id *next;
  209. struct field_id *field;
  210. };
  211. struct key_id {
  212. char field_id[80];
  213. struct key_id *next;
  214. struct field_id *field;
  215. };
  216. struct finclude {
  217. char field_id[80];
  218. int value;
  219. struct finclude *next;
  220. };
  221. struct include {
  222. char line_id[80];
  223. int value;
  224. struct include *next;
  225. };
  226. /************************************************/
  227. /* */
  228. /* GLOBALS */
  229. /* */
  230. /************************************************/
  231. char abstracter[100];
  232. int abstract = GENERATE;
  233. struct key_id *abstract_table = NULL;
  234. /***nl_catd dtsearch_catd = (nl_catd) -1;***/
  235. int bad_parm = FALSE;
  236. int bad_profile = FALSE;
  237. int bot_defined = FALSE;
  238. struct date_id *date_table = NULL;
  239. int date_pos_defined = FALSE;
  240. static char *del_string = " +=,\t\n";
  241. /****static char *del_string = " +-=,\t\n";**allow neg nums***/
  242. int del_blanklines = FALSE;
  243. char dicname[10] = {0};
  244. char dicpath[_POSIX_PATH_MAX] = {0};
  245. int discard = TRUE;
  246. int discard_record = FALSE;
  247. struct finclude *finclude_tab = NULL;
  248. struct field_id *field_table = NULL;
  249. struct include *i_i_t = NULL;
  250. int imagemode = INCLUDE;
  251. int imageflag = INCLUDE;
  252. struct include *include_tab = NULL;
  253. char *infile;
  254. static FILE *instream = NULL;
  255. static long key_count = 0;
  256. struct key_id *key_table = NULL;
  257. int key_defined = FALSE;
  258. int key_pos_defined = FALSE;
  259. char key_char;
  260. char key_value[80];
  261. static char *line_mode = " CTHULHU TOCOMA ZYYXY UTOPIA";
  262. struct line_id *line_table = NULL;
  263. time_t now;
  264. char now_str[24];
  265. struct tm nowtm;
  266. static int null_date_specified = FALSE;
  267. struct tm *objdate_tmptr;
  268. int outcount = 0;
  269. char outmode[8] = "w";
  270. int outmode_specified = FALSE;
  271. char *outfile;
  272. static FILE *outstream = NULL;
  273. char *profile;
  274. static long rec_count = 0L; /* for err msgs */
  275. struct rec *record_head = NULL;
  276. struct tm rectm;
  277. int screen_width = 79;
  278. int shutdown_now = FALSE;
  279. int started = FALSE;
  280. int textflag = INCLUDE;
  281. int textmode = INCLUDE;
  282. int top_defined = FALSE;
  283. struct line_id *top_rec;
  284. char top_rec_name[80];
  285. int uppercase = FALSE;
  286. int uninit_line = TRUE;
  287. int uninit_field = TRUE;
  288. int warnings = TRUE;
  289. int wordmode = INCLUDE;
  290. /****************************************************************
  291. VALIDATE_ID - validates an indentifier (first character a
  292. letter, then alpha-numeric, etc)
  293. ****************************************************************/
  294. int validate_id (char *s)
  295. {
  296. int i;
  297. if (s==NULL)
  298. return FALSE;
  299. if (!isalpha (s[0])) {
  300. return FALSE;
  301. }
  302. for (i = 1; i < strlen (s); i++)
  303. if (!isalnum (s[i]) && s[i] != '_') {
  304. return FALSE;
  305. }
  306. return TRUE;
  307. }
  308. /****************************************************************
  309. OPEN_OUTFILE - open outputfile - if the file already exists,
  310. and no mode was specified by the user, ask the user what to do.
  311. ****************************************************************/
  312. void open_outfile (void)
  313. {
  314. FILE *temp;
  315. int i;
  316. if (!outmode_specified)
  317. if ((temp = fopen (outfile, "r")) != NULL) {
  318. fclose (temp);
  319. printf ( CATGETS(dtsearch_catd, MS_chandel, 3,
  320. "Output file '%s' already exists.\n") ,
  321. outfile);
  322. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 4,
  323. "Append, overwrite, or quit? [a,o,q] ") );
  324. i = tolower (getchar ());
  325. if (i == 'a')
  326. strcpy (outmode, "a");
  327. else if (i == 'o')
  328. strcpy (outmode, "w");
  329. else
  330. exit (FILE_ERROR);
  331. }
  332. if (!strcmp (outfile, "-"))
  333. outstream = stdout;
  334. else {
  335. if ((outstream = fopen (outfile, outmode)) == NULL) {
  336. printf ( CATGETS(dtsearch_catd, MS_chandel, 7,
  337. "Unable to open output file '%s'.\n") , outfile);
  338. exit (FILE_ERROR);
  339. }
  340. }
  341. return;
  342. } /* open_outfile */
  343. /****************************************************************
  344. IS_TIME - returns TRUE if the passed string contains the
  345. string "time" in any case (upper/lower) - without destroying the
  346. original string, in case it was a field name.
  347. ****************************************************************/
  348. int is_time (char *orig)
  349. {
  350. char *s;
  351. int i;
  352. /* copy original string to temp buffer, so we can manipulate */
  353. s = (char *) malloc (sizeof (char) * strlen (orig) +5);
  354. strcpy (s, orig);
  355. for (i = 0; i < strlen (s); i++)
  356. s[i] = tolower (s[i]);
  357. if (strcmp (s, "time") == 0)
  358. return TRUE;
  359. else
  360. return FALSE;
  361. }
  362. /****************************************************************
  363. IS_COUNT - returns TRUE if the passed string contains the
  364. string "count" in any case (upper/lower) - without destroying the
  365. original string, in case it was a field name.
  366. ****************************************************************/
  367. int is_count (char *orig)
  368. {
  369. char *s;
  370. int i;
  371. /* copy original string to temp buffer, so we can manipulate */
  372. s = (char *) malloc (sizeof(char) * strlen(orig) +5);
  373. strcpy (s, orig);
  374. for (i = 0; i < strlen (s); i++)
  375. s[i] = tolower (s[i]);
  376. if (strcmp (s, "count") == 0)
  377. return TRUE;
  378. else
  379. return FALSE;
  380. }
  381. /****************************************************************
  382. MY_STRTOK - my own version of strtok - why? Because I need
  383. a little flexibility when parsing out the string component -
  384. what if it has quotes embedded?
  385. s1 = the line to be parsed (= start at beginning)
  386. or NULL (= start where we last left off).
  387. s2 = the 'delete' string or array of token separators.
  388. Usually it is either the global 'del_string' (" +-=,\t\n")
  389. or a string consisting of a single double-quote char.
  390. ****************************************************************/
  391. char *my_strtok (char *s1, const char *s2)
  392. {
  393. char *sbegin, *send;
  394. static char stringbuf[100];
  395. static char *ssave = "";
  396. int i = 0;
  397. memset (stringbuf, 0, sizeof(stringbuf));
  398. sbegin = (s1) ? s1 : ssave; /* start of string or where we last left off */
  399. if (strcmp (s2, "\"") == 0) { /* parsing for a string */
  400. if (*sbegin == '\0') {
  401. ssave = "";
  402. return NULL;
  403. }
  404. while (*sbegin != '"' && *sbegin != '\0') {/*-- look for first " --*/
  405. sbegin++;
  406. }
  407. if (*sbegin == '\0') {
  408. ssave = "";
  409. return NULL;
  410. }
  411. sbegin++; /*-- skip past " --*/
  412. i = 0;
  413. while (*sbegin != '"') {/*-- until other " --*/
  414. if (*sbegin == '\\') /*-- escape sequence --*/
  415. sbegin++;
  416. if (*sbegin == '\0') { /*-- end of line --*/
  417. ssave = "";
  418. return NULL;
  419. }
  420. stringbuf[i++] = (*sbegin);
  421. sbegin++;
  422. }
  423. send = sbegin;
  424. *send++ = '\0';
  425. ssave = send;
  426. stringbuf[i] = 0;
  427. sbegin = stringbuf;
  428. return (sbegin);
  429. }
  430. else { /* not parsing for a string */
  431. sbegin += strspn (sbegin, s2);
  432. if (*sbegin == '\0') {
  433. ssave = "";
  434. return NULL;
  435. } /* if */
  436. send = strpbrk (sbegin, s2);
  437. if (*send != '\0')
  438. *send++ = '\0';
  439. ssave = send;
  440. return (sbegin);
  441. } /* else */
  442. } /*-- my_strtok --*/
  443. /****************************************************************
  444. IS_BLANK - determines if a string contains nothing but
  445. white space.
  446. *****************************************************************/
  447. int is_blank (char *s)
  448. {
  449. int i;
  450. for (i = 0; i < strlen (s); i++)
  451. if (!isspace (s[i]))
  452. return 0;
  453. return 1;
  454. } /*-- is_blank --*/
  455. /***********************************************************************
  456. TOKEN - returns a numerical token for the defined identifier types
  457. ************************************************************************/
  458. int token (char *s)
  459. {
  460. int i;
  461. if (s == NULL)
  462. return UNKNOWN;
  463. /*-- make token all lowercase --*/
  464. for (i = 0; i < strlen (s); i++)
  465. s[i] = tolower (s[i]);
  466. if (!strcmp (s, "line"))
  467. return LINE;
  468. if (!strcmp (s, "field"))
  469. return FIELD;
  470. if (!strcmp (s, "key"))
  471. return KEY;
  472. if (!strcmp (s, "date"))
  473. return DATEFLD;
  474. if (!strcmp (s, "text"))
  475. return TEXT;
  476. if (!strcmp (s, "keychar"))
  477. return KEYCHAR;
  478. if (!strcmp (s, "delimiter"))
  479. return DELIMITER;
  480. if (!strcmp (s, "textinclude"))
  481. return TEXTINCLUDE;
  482. if (!strcmp (s, "textexclude"))
  483. return TEXTEXCLUDE;
  484. if (!strcmp (s, "tfieldinclude"))
  485. return TFIELDINCLUDE;
  486. if (!strcmp (s, "tfieldexclude"))
  487. return TFIELDEXCLUDE;
  488. if (!strcmp (s, "delblanklines"))
  489. return DELBLANKLINES;
  490. if (!strcmp (s, "abstract"))
  491. return ABSTR;
  492. if (!strcmp (s, "user"))
  493. return USER;
  494. if (!strcmp (s, "fields"))
  495. return FIELDS;
  496. if (!strcmp (s, "generate"))
  497. return GENERATE;
  498. if (!strcmp (s, "image"))
  499. return IMAGE;
  500. if (!strcmp (s, "imageinclude"))
  501. return IMAGEINCLUDE;
  502. if (!strcmp (s, "imageexclude"))
  503. return IMAGEEXCLUDE;
  504. if (!strcmp (s, "discard"))
  505. return DISCARD;
  506. if (!strcmp (s, "constant"))
  507. return CONSTANT;
  508. if (!strcmp (s, "upper"))
  509. return UPPER;
  510. return UNKNOWN;
  511. } /*-- token --*/
  512. /***********************************************************************
  513. PROCESS_PROFILE - process 'profile' file.
  514. ************************************************************************/
  515. void process_profile (void)
  516. {
  517. FILE *prof;
  518. char prof_line[200];
  519. int line_num = 0;
  520. int i;
  521. char *tok;
  522. struct line_id *line_current = NULL;
  523. struct field_id *field_current = NULL;
  524. struct key_id *key_current;
  525. struct date_id *date_current;
  526. struct key_id *abstract_current = NULL;
  527. struct finclude *finclude_current = NULL;
  528. struct include *include_current = NULL;
  529. struct include *i_i_current = NULL;
  530. int found;
  531. int tok_type;
  532. /*-- open file --*/
  533. if ((prof = fopen (profile, "r")) == NULL) {
  534. printf ( CATGETS(dtsearch_catd, MS_chandel, 11,
  535. "\nError - unable to open profile file '%s'.\n") , profile);
  536. exit (FILE_ERROR);
  537. }
  538. /*-- Get next line --*/
  539. do {
  540. char *ret = NULL;
  541. ret = fgets (prof_line, 200, prof);
  542. line_num++;
  543. if (ret == NULL || feof (prof) )
  544. break;
  545. if (prof_line[0] == '#' || is_blank (prof_line))
  546. continue;
  547. tok = my_strtok (prof_line, del_string);
  548. if (tok == NULL)
  549. continue; /* ignore blank line */
  550. tok_type = token (tok);
  551. switch (tok_type) {
  552. case UPPER:
  553. uppercase = TRUE;
  554. break;
  555. case LINE:
  556. /*-- build node --*/
  557. if (line_table == NULL) {
  558. line_table = (struct line_id *) malloc (
  559. sizeof (struct line_id));
  560. line_current = line_table;
  561. line_table->next = NULL;
  562. line_table->comp = (struct line_comp *) malloc (
  563. sizeof (struct line_comp));
  564. line_table->head = line_table->comp;
  565. line_table->comp->next = NULL;
  566. }
  567. /* if */
  568. else {
  569. line_current->next = (struct line_id *) malloc (
  570. sizeof (struct line_id));
  571. line_current = line_current->next;
  572. line_current->next = NULL;
  573. line_current->comp = (struct line_comp *) malloc (
  574. sizeof (struct line_comp));
  575. line_current->head = line_current->comp;
  576. line_current->comp->next = NULL;
  577. } /* else */
  578. line_current->image_action = NONE;
  579. line_current->word_action = NONE;
  580. line_current->text_action = NONE;
  581. line_current->line = NULL;
  582. line_current->name[0] = 0;
  583. /*-- get identifier --*/
  584. tok = my_strtok ('\0', del_string);
  585. if (validate_id (tok))
  586. strcpy (line_current->name, tok);
  587. else {
  588. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  589. "Error line %d: invalid identifier '%s'.\n") ,
  590. line_num, NULLORSTR(tok));
  591. bad_profile = TRUE;
  592. break;
  593. }
  594. /*-- get first value token --*/
  595. tok = my_strtok ('\0', del_string);
  596. if (!tok) {
  597. printf ( CATGETS(dtsearch_catd, MS_chandel, 13,
  598. "Error line %d - identifier '%s' missing value(s).\n") ,
  599. line_num, line_current->name);
  600. bad_profile = TRUE;
  601. continue;
  602. } /* if */
  603. if (!strcmp (tok, "*"))
  604. line_current->comp->column_number = ANY;
  605. else
  606. line_current->comp->column_number = atoi (tok);
  607. if (line_current->comp->column_number == 0) {
  608. printf ( CATGETS(dtsearch_catd, MS_chandel, 14,
  609. "Error line %d - zero or bad value for '%s'.\n"
  610. " offensive token: %s.\n") ,
  611. line_num, line_current->name, tok);
  612. bad_profile = TRUE;
  613. continue;
  614. } /* if */
  615. /* d d d-- get second token of pair -- */
  616. tok = my_strtok ('\0', "\"");
  617. if (!tok) {
  618. if (line_current->comp->column_number == ANY) {
  619. printf ( CATGETS(dtsearch_catd, MS_chandel, 15,
  620. "Error line %d - for identifier '%s', column has "
  621. "been set to ANY\n but there is no "
  622. "identifying signature string.\n") ,
  623. line_num, line_current->name);
  624. bad_profile = TRUE;
  625. continue;
  626. }
  627. /* if (line.. */
  628. else {
  629. strcpy (line_current->comp->text, line_mode);
  630. continue;
  631. } /* else */
  632. }
  633. /* if (!tok) */
  634. else {
  635. strcpy (line_current->comp->text, tok);
  636. line_current->comp->text_length =
  637. strlen (line_current->comp->text);
  638. }
  639. /*-- check for more tokens for LINE type of line --*/
  640. for(;;) {
  641. tok = my_strtok ('\0', del_string);
  642. if (!tok)
  643. break;
  644. /*-- build component node --*/
  645. line_current->comp->next = (struct line_comp *) malloc (
  646. sizeof (struct line_comp));
  647. line_current->comp = line_current->comp->next;
  648. line_current->comp->next = NULL;
  649. /*-- check # and store --*/
  650. if (!strcmp (tok, "*"))
  651. line_current->comp->column_number = ANY;
  652. else
  653. line_current->comp->column_number = atoi (tok);
  654. if (line_current->comp->column_number == 0) {
  655. printf ( CATGETS(dtsearch_catd, MS_chandel, 16,
  656. "Error line %d - zero or bad value for "
  657. "identifier '%s'\n offensive token: %s.\n") ,
  658. line_num, line_current->name, tok);
  659. bad_profile = TRUE;
  660. continue;
  661. } /* if (line.. */
  662. /* - --- get second of pair -- */
  663. tok = my_strtok ('\0', "\"");
  664. if (!tok) {
  665. if (line_current->comp->column_number == ANY)
  666. printf ( CATGETS(dtsearch_catd, MS_chandel, 15,
  667. "Error line %d - for identifier '%s', column has "
  668. "been set to ANY\n but there is no "
  669. "identifying signature string.\n") ,
  670. line_num, line_current->name);
  671. else
  672. printf ( CATGETS(dtsearch_catd, MS_chandel, 18,
  673. "Error line %d - missing value for "
  674. "identifier '%s'\n") ,
  675. line_num, line_current->name);
  676. bad_profile = TRUE;
  677. continue;
  678. } /* if (!tok) */
  679. strcpy (line_current->comp->text, tok);
  680. line_current->comp->text_length =
  681. strlen (line_current->comp->text);
  682. } /* end for(;;) loop for continuing LINE token pairs */
  683. break; /* end case LINE */
  684. case CONSTANT:
  685. case FIELD:
  686. if (field_table == NULL) {
  687. field_table = (struct field_id *)
  688. malloc (sizeof (struct field_id));
  689. field_current = field_table;
  690. field_table->next = NULL;
  691. }
  692. else {
  693. field_current->next = (struct field_id *) malloc (
  694. sizeof (struct field_id));
  695. field_current = field_current->next;
  696. field_current->next = NULL;
  697. }
  698. memset (field_current, 0, sizeof(struct field_id));
  699. field_current->word_action = NONE;
  700. field_current->image_action = NONE;
  701. field_current->text_action = NONE;
  702. if (tok_type == CONSTANT)
  703. field_current->constant = TRUE;
  704. /*-- get identifier --*/
  705. tok = my_strtok ('\0', del_string);
  706. if (validate_id (tok)) {
  707. strcpy (field_current->name, tok);
  708. if (strncmp (tok, "MMM", 3) == 0)
  709. field_current->is_month = TRUE;
  710. }
  711. else {
  712. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  713. "Error line %d: invalid identifier '%s'.\n") ,
  714. line_num, NULLORSTR(tok));
  715. bad_profile = TRUE;
  716. break;
  717. }
  718. if (field_current->constant) {
  719. /*-- get constant value --*/
  720. tok = my_strtok (NULL, "\"");
  721. if (!tok) {
  722. printf ( CATGETS(dtsearch_catd, MS_chandel, 93,
  723. "Error line %d - '%s' string not "
  724. "enclosed in double quotes.\n"),
  725. line_num, field_current->name);
  726. bad_profile = TRUE;
  727. continue;
  728. }
  729. strcpy (field_current->value, tok);
  730. } /* end CONSTANT */
  731. else { /* ...must be FIELD */
  732. /*-- get line id --*/
  733. tok = my_strtok ('\0', del_string);
  734. if (!tok) {
  735. printf ( CATGETS(dtsearch_catd, MS_chandel, 13,
  736. "Error line %d - identifier '%s' missing value(s).\n") ,
  737. line_num, line_current->name);
  738. bad_profile = TRUE;
  739. continue;
  740. } /* if */
  741. strcpy (field_current->line_id, tok);
  742. /*-- get "string" --*/
  743. tok = my_strtok ('\0', "\"");
  744. if (!tok) {
  745. printf ( CATGETS(dtsearch_catd, MS_chandel, 93,
  746. "Error line %d - '%s' string not "
  747. "enclosed in double quotes.\n"),
  748. line_num, field_current->name);
  749. bad_profile = TRUE;
  750. continue;
  751. }
  752. snprintf(field_current->text, sizeof(field_current->text), "%s", tok);
  753. field_current->text_length = strlen (field_current->text);
  754. /*-- get offset --*/
  755. tok = my_strtok ('\0', del_string);
  756. if (!tok) {
  757. printf ( CATGETS(dtsearch_catd, MS_chandel, 13,
  758. "Error line %d - identifier '%s' missing value(s).\n") ,
  759. line_num, line_current->name);
  760. bad_profile = TRUE;
  761. continue;
  762. } /* if */
  763. field_current->offset = atoi (tok);
  764. /*-- get length --*/
  765. tok = my_strtok ('\0', del_string);
  766. /*******if (!tok && field_current->length == ANY) ************/
  767. if (!tok) {
  768. printf ( CATGETS(dtsearch_catd, MS_chandel, 13,
  769. "Error line %d - identifier '%s' missing value(s).\n") ,
  770. line_num, line_current->name);
  771. bad_profile = TRUE;
  772. continue;
  773. } /* if */
  774. if (!strcmp (tok, "eoln"))
  775. field_current->defined_length = EOLN;
  776. else if (!strcmp (tok, "eow"))
  777. field_current->defined_length = EOW;
  778. else
  779. field_current->defined_length = atoi (tok);
  780. } /* end FIELD */
  781. break;
  782. case DELIMITER:
  783. /*-- get next token - should be name of line --*/
  784. if (warnings &&(bot_defined || top_defined))
  785. printf ( CATGETS(dtsearch_catd, MS_chandel, 23,
  786. "Warning line %d: Delimiter redefined.\n") ,
  787. line_num);
  788. tok = my_strtok ('\0', del_string);
  789. if (validate_id (tok))
  790. strcpy (top_rec_name, tok);
  791. else {
  792. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  793. "Error line %d: invalid identifier '%s'.\n"),
  794. line_num, NULLORSTR(tok));
  795. bad_profile = TRUE;
  796. }
  797. tok = my_strtok ('\0', del_string);
  798. if (tok == NULL)
  799. goto BAD_DELIM_VAL;
  800. /* convert tok to lowercase */
  801. for (i = 0; i < strlen (tok); i++)
  802. tok[i] = tolower (tok[i]);
  803. if (!strcmp (tok, "top")) {
  804. top_defined = TRUE;
  805. bot_defined = FALSE;
  806. } else if (!strcmp (tok, "bottom")) {
  807. top_defined = FALSE;
  808. bot_defined = TRUE;
  809. } else {
  810. BAD_DELIM_VAL:
  811. printf ( CATGETS(dtsearch_catd, MS_chandel, 25,
  812. "Error line %d: delimiter not specified as "
  813. "'top' or 'bottom'.\n") ,
  814. line_num);
  815. bad_profile = TRUE;
  816. }
  817. break;
  818. case TFIELDEXCLUDE:
  819. tok = my_strtok ('\0', del_string);
  820. if (validate_id (tok)) {
  821. if (finclude_tab == NULL) {
  822. finclude_tab = (struct finclude *) malloc (
  823. sizeof (struct finclude));
  824. finclude_current = finclude_tab;
  825. } else {
  826. finclude_current->next = (struct finclude *) malloc (
  827. sizeof (struct finclude));
  828. finclude_current = finclude_current->next;
  829. }
  830. finclude_current->next = NULL;
  831. strcpy (finclude_current->field_id, tok);
  832. finclude_current->value = EXCLUDE;
  833. }
  834. /* if it was a valid token */
  835. else {
  836. printf ( CATGETS(dtsearch_catd, MS_chandel, 26,
  837. "Error line %d: invalid token '%s'.\n") ,
  838. line_num, NULLORSTR(tok));
  839. bad_profile = TRUE;
  840. }
  841. break;
  842. case TFIELDINCLUDE:
  843. tok = my_strtok ('\0', del_string);
  844. if (validate_id (tok)) {
  845. if (finclude_tab == NULL) {
  846. finclude_tab = (struct finclude *) malloc (
  847. sizeof (struct finclude));
  848. finclude_tab->next = NULL;
  849. finclude_current = finclude_tab;
  850. }
  851. /* if valid */
  852. else {
  853. finclude_current->next = (struct finclude *) malloc (
  854. sizeof (struct finclude));
  855. finclude_current = finclude_current->next;
  856. finclude_current->next = NULL;
  857. } /* else valid */
  858. strcpy (finclude_current->field_id, tok);
  859. finclude_current->value = INCLUDE;
  860. }
  861. /* if it was a valid token */
  862. else {
  863. printf ( CATGETS(dtsearch_catd, MS_chandel, 27,
  864. "Error line %d: invalid token '%s'.\n") ,
  865. line_num, NULLORSTR(tok));
  866. bad_profile = TRUE;
  867. }
  868. break;
  869. case TEXTEXCLUDE:
  870. tok = my_strtok ('\0', del_string);
  871. if (validate_id (tok)) {
  872. if (include_tab == NULL) {
  873. include_tab = (struct include *) malloc (
  874. sizeof (struct include));
  875. include_tab->next = NULL;
  876. include_current = include_tab;
  877. }
  878. /* if valid */
  879. else {
  880. include_current->next = (struct include *) malloc (
  881. sizeof (struct include));
  882. include_current = include_current->next;
  883. include_current->next = NULL;
  884. } /* else in valid */
  885. strcpy (include_current->line_id, tok);
  886. tok = my_strtok ('\0', del_string);
  887. if (tok == NULL)
  888. include_current->value = EXCLUDE;
  889. else {
  890. if (validate_id (tok)) {
  891. include_current->value = SET;
  892. include_current->next = (struct include *) malloc (
  893. sizeof (struct include));
  894. include_current = include_current->next;
  895. include_current->next = NULL;
  896. strcpy (include_current->line_id, tok);
  897. include_current->value = DEFAULT;
  898. }
  899. /* if in else */
  900. else {
  901. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  902. "Error line %d: invalid identifier '%s'.\n") ,
  903. line_num, tok);
  904. bad_profile = TRUE;
  905. } /* else in else */
  906. } /* else tok wasn't NULL */
  907. }
  908. /* if validate... */
  909. else {
  910. printf (CATGETS(dtsearch_catd, MS_chandel, 12,
  911. "Error line %d: invalid identifier '%s'.\n") ,
  912. line_num, NULLORSTR(tok));
  913. bad_profile = TRUE;
  914. } /* else not a valid token */
  915. break;
  916. case IMAGEEXCLUDE:
  917. tok = my_strtok ('\0', del_string);
  918. if (validate_id (tok)) {
  919. if (i_i_t == NULL) {
  920. i_i_t = (struct include *) malloc (
  921. sizeof (struct include));
  922. i_i_t->next = NULL;
  923. i_i_current = i_i_t;
  924. }
  925. /* if in valid */
  926. else {
  927. i_i_current->next = (struct include *) malloc (
  928. sizeof (struct include));
  929. i_i_current = i_i_current->next;
  930. i_i_current->next = NULL;
  931. } /* else in valid */
  932. strcpy (i_i_current->line_id, tok);
  933. tok = my_strtok ('\0', del_string);
  934. if (tok == NULL)
  935. i_i_current->value = EXCLUDE;
  936. else {
  937. if (validate_id (tok)) {
  938. i_i_current->value = SET;
  939. i_i_current->next = (struct include *) malloc (
  940. sizeof (struct include));
  941. i_i_current = i_i_current->next;
  942. i_i_current->next = NULL;
  943. strcpy (i_i_current->line_id, tok);
  944. i_i_current->value = DEFAULT;
  945. }
  946. /* if in else */
  947. else {
  948. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  949. "Error line %d: invalid identifier '%s'.\n") ,
  950. line_num, tok);
  951. bad_profile = TRUE;
  952. } /* else in else */
  953. } /* else tok wasn't NULL */
  954. }
  955. /* if validate... */
  956. else {
  957. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  958. "Error line %d: invalid identifier '%s'.\n") ,
  959. line_num, NULLORSTR(tok));
  960. bad_profile = TRUE;
  961. } /* else not a valid token */
  962. break;
  963. case IMAGEINCLUDE:
  964. tok = my_strtok ('\0', del_string);
  965. if (validate_id (tok)) {
  966. if (i_i_t == NULL) {
  967. i_i_t = (struct include *) malloc (
  968. sizeof (struct include));
  969. i_i_t->next = NULL;
  970. i_i_current = i_i_t;
  971. }
  972. /* if in valid */
  973. else {
  974. i_i_current->next = (struct include *) malloc (
  975. sizeof (struct include));
  976. i_i_current = i_i_current->next;
  977. i_i_current->next = NULL;
  978. } /* else in valid */
  979. strcpy (i_i_current->line_id, tok);
  980. tok = my_strtok ('\0', del_string);
  981. if (tok == NULL)
  982. i_i_current->value = INCLUDE;
  983. else {
  984. if (validate_id (tok)) {
  985. i_i_current->value = CLEAR;
  986. i_i_current->next = (struct include *) malloc (
  987. sizeof (struct include));
  988. i_i_current = i_i_current->next;
  989. i_i_current->next = NULL;
  990. strcpy (i_i_current->line_id, tok);
  991. i_i_current->value = DEFAULT;
  992. }
  993. /* if in else */
  994. else {
  995. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  996. "Error line %d: invalid identifier '%s'.\n") ,
  997. line_num, tok);
  998. bad_profile = TRUE;
  999. } /* else in else */
  1000. } /* else tok wasn't NULL */
  1001. }
  1002. /* if validate... */
  1003. else {
  1004. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  1005. "Error line %d: invalid identifier '%s'.\n") ,
  1006. line_num, NULLORSTR(tok));
  1007. bad_profile = TRUE;
  1008. } /* else not a valid token */
  1009. break;
  1010. case TEXTINCLUDE:
  1011. tok = my_strtok ('\0', del_string);
  1012. if (validate_id (tok)) {
  1013. if (include_tab == NULL) {
  1014. include_tab = (struct include *) malloc (
  1015. sizeof (struct include));
  1016. include_tab->next = NULL;
  1017. include_current = include_tab;
  1018. }
  1019. /* if in valid */
  1020. else {
  1021. include_current->next = (struct include *) malloc (
  1022. sizeof (struct include));
  1023. include_current = include_current->next;
  1024. include_current->next = NULL;
  1025. } /* else in valid */
  1026. strcpy (include_current->line_id, tok);
  1027. tok = my_strtok ('\0', del_string);
  1028. if (tok == NULL)
  1029. include_current->value = INCLUDE;
  1030. else {
  1031. if (validate_id (tok)) {
  1032. include_current->value = CLEAR;
  1033. include_current->next = (struct include *) malloc (
  1034. sizeof (struct include));
  1035. include_current = include_current->next;
  1036. include_current->next = NULL;
  1037. strcpy (include_current->line_id, tok);
  1038. include_current->value = DEFAULT;
  1039. }
  1040. /* if in else */
  1041. else {
  1042. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  1043. "Error line %d: invalid identifier '%s'.\n") ,
  1044. line_num, tok);
  1045. bad_profile = TRUE;
  1046. } /* else in else */
  1047. } /* else tok wasn't NULL */
  1048. }
  1049. /* if validate... */
  1050. else {
  1051. printf ( CATGETS(dtsearch_catd, MS_chandel, 12,
  1052. "Error line %d: invalid identifier '%s'.\n") ,
  1053. line_num, NULLORSTR(tok));
  1054. bad_profile = TRUE;
  1055. } /* else not a valid token */
  1056. break;
  1057. case IMAGE:
  1058. tok = my_strtok ('\0', del_string);
  1059. if (tok == NULL)
  1060. goto BAD_IMAGE;
  1061. for (i = 0; i < strlen (tok); i++)
  1062. tok[i] = tolower (tok[i]);
  1063. if (strcmp (tok, CATGETS(dtsearch_catd, MS_chandel, 34,"all")) == 0)
  1064. imagemode = INCLUDE;
  1065. else if (strcmp (tok, CATGETS(dtsearch_catd, MS_chandel, 35, "none")) == 0)
  1066. imagemode = EXCLUDE;
  1067. else {
  1068. BAD_IMAGE:
  1069. printf ( CATGETS(dtsearch_catd, MS_chandel, 36,
  1070. "Error line %d: image mode must be 'all' or "
  1071. "'none' -'%s' not recognized.\n") ,
  1072. NULLORSTR(tok));
  1073. bad_profile = TRUE;
  1074. }
  1075. imageflag = imagemode;
  1076. break;
  1077. case TEXT:
  1078. tok = my_strtok ('\0', del_string);
  1079. if (tok == NULL)
  1080. goto BAD_TEXT;
  1081. for (i = 0; i < strlen (tok); i++)
  1082. tok[i] = tolower (tok[i]);
  1083. if (strcmp (tok, "all") == 0)
  1084. textmode = INCLUDE;
  1085. else if (strcmp (tok, "none") == 0)
  1086. textmode = EXCLUDE;
  1087. else {
  1088. BAD_TEXT:
  1089. printf ( CATGETS(dtsearch_catd, MS_chandel, 37,
  1090. "Error line %d: text mode must be 'all' or "
  1091. "'none' - '%s' not recognized.\n") , NULLORSTR(tok));
  1092. bad_profile = TRUE;
  1093. }
  1094. textflag = textmode;
  1095. break;
  1096. case KEYCHAR:
  1097. /*-- get next token - should be character for key type --*/
  1098. if (warnings && key_defined)
  1099. printf ( CATGETS(dtsearch_catd, MS_chandel, 38,
  1100. "Warning line %d: Key character redefined.\n") ,
  1101. line_num);
  1102. tok = my_strtok ('\0', del_string);
  1103. if (validate_id (tok))
  1104. key_char = tok[0];
  1105. else {
  1106. printf ( CATGETS(dtsearch_catd, MS_chandel, 39,
  1107. "Error line %d: invalid Key Character:'%c'.\n") ,
  1108. line_num, (tok)?tok[0]:'?');
  1109. bad_profile = TRUE;
  1110. }
  1111. key_defined = TRUE;
  1112. break;
  1113. case DATEFLD:
  1114. if (date_pos_defined) {
  1115. printf ( CATGETS(dtsearch_catd, MS_chandel, 110,
  1116. "Warning line %d - date field redefined.\n") ,
  1117. line_num);
  1118. null_date_specified = FALSE;
  1119. }
  1120. date_table = (struct date_id *) malloc
  1121. (sizeof (struct date_id));
  1122. date_current = date_table;
  1123. date_current->next = NULL;
  1124. tok = my_strtok ('\0', del_string);
  1125. /* validate_id() just does syntax chk on name string */
  1126. if (validate_id (tok))
  1127. strcpy (date_current->field_id, tok);
  1128. else {
  1129. /* Msg #111 used two places */
  1130. printf ( CATGETS(dtsearch_catd, MS_chandel, 111,
  1131. "Error line %d - bad identifier '%s' for date.\n") ,
  1132. line_num, NULLORSTR(tok));
  1133. bad_profile = TRUE;
  1134. break;
  1135. }
  1136. /* Test for special "null" date value */
  1137. if (strcmp (date_current->field_id, "null") == 0) {
  1138. date_pos_defined = TRUE;
  1139. null_date_specified = TRUE;
  1140. break;
  1141. }
  1142. tok = my_strtok ('\0', del_string);
  1143. while (tok != NULL) {
  1144. date_current->next = (struct date_id *) malloc
  1145. (sizeof (struct date_id));
  1146. date_current = date_current->next;
  1147. date_current->next = NULL;
  1148. if (validate_id (tok))
  1149. strcpy (date_current->field_id, tok);
  1150. else {
  1151. /* Msg #111 used two places */
  1152. printf ( CATGETS(dtsearch_catd, MS_chandel, 111,
  1153. "Error line %d - bad identifier '%s' for date.\n"),
  1154. line_num, NULLORSTR(tok));
  1155. bad_profile = TRUE;
  1156. break;
  1157. }
  1158. tok = my_strtok ('\0', del_string);
  1159. }
  1160. date_pos_defined = TRUE;
  1161. break; /* end case DATEFLD */
  1162. case KEY:
  1163. /*-- building the key --*/
  1164. if (warnings && key_pos_defined)
  1165. printf ( CATGETS(dtsearch_catd, MS_chandel, 40,
  1166. "Warning line %d - key field redefined.\n") ,
  1167. line_num);
  1168. key_table = (struct key_id *) malloc (sizeof (struct key_id));
  1169. key_current = key_table;
  1170. key_current->next = NULL;
  1171. tok = my_strtok ('\0', del_string);
  1172. if (validate_id (tok)) {
  1173. if (is_time (tok)) {
  1174. strcpy (key_current->field_id, "time");
  1175. key_pos_defined = TRUE;
  1176. break;
  1177. } else if (is_count (tok)) {
  1178. strcpy (key_current->field_id, "count");
  1179. key_pos_defined = TRUE;
  1180. break;
  1181. } else
  1182. strcpy (key_current->field_id, tok);
  1183. }
  1184. else {
  1185. printf ( CATGETS(dtsearch_catd, MS_chandel, 43,
  1186. "Error line %d - bad identifier '%s' for key.\n") ,
  1187. line_num, NULLORSTR(tok));
  1188. bad_profile = TRUE;
  1189. break;
  1190. }
  1191. tok = my_strtok ('\0', del_string);
  1192. while (tok != NULL) {
  1193. key_current->next = (struct key_id *) malloc (
  1194. sizeof (struct key_id));
  1195. key_current = key_current->next;
  1196. key_current->next = NULL;
  1197. if (validate_id (tok))
  1198. strcpy (key_current->field_id, tok);
  1199. else {
  1200. printf ( CATGETS(dtsearch_catd, MS_chandel, 43,
  1201. "Error line %d - bad identifier '%s' for key.\n") ,
  1202. line_num, tok);
  1203. bad_profile = TRUE;
  1204. break;
  1205. }
  1206. tok = my_strtok ('\0', del_string);
  1207. }
  1208. key_pos_defined = TRUE;
  1209. break;
  1210. case DISCARD:
  1211. tok = my_strtok ('\0', del_string);
  1212. if (tok == NULL)
  1213. goto BAD_DISCARD;
  1214. for (i = 0; i < strlen (tok); i++)
  1215. tok[i] = toupper (tok[i]);
  1216. if (!strcmp (tok, "TRUE"))
  1217. discard = TRUE;
  1218. else if (!strcmp (tok, "FALSE"))
  1219. discard = FALSE;
  1220. else {
  1221. BAD_DISCARD:
  1222. printf ( CATGETS(dtsearch_catd, MS_chandel, 45,
  1223. "Error line %d: unknown option for 'discard': "
  1224. "'%s'.\n") , line_num, NULLORSTR(tok));
  1225. bad_profile = TRUE;
  1226. }
  1227. break;
  1228. case DELBLANKLINES:
  1229. tok = my_strtok ('\0', del_string);
  1230. if (tok == NULL)
  1231. goto BAD_DELBLANKLINES;
  1232. for (i = 0; i < strlen (tok); i++)
  1233. tok[i] = toupper (tok[i]);
  1234. if (!strcmp (tok, "TRUE"))
  1235. del_blanklines = TRUE;
  1236. else if (!strcmp (tok, "FALSE"))
  1237. del_blanklines = FALSE;
  1238. else {
  1239. BAD_DELBLANKLINES:
  1240. printf ( CATGETS(dtsearch_catd, MS_chandel, 46,
  1241. "Error line %d: unknown option for "
  1242. "'delblanklines': '%s'.\n") ,
  1243. line_num, NULLORSTR(tok));
  1244. bad_profile = TRUE;
  1245. }
  1246. break;
  1247. case ABSTR:
  1248. tok = my_strtok ('\0', del_string);
  1249. abstract = token (tok);
  1250. switch (abstract) {
  1251. case GENERATE:
  1252. break;
  1253. case USER:
  1254. tok = my_strtok ('\0', del_string);
  1255. if (tok == NULL)
  1256. goto BAD_ABSTR;
  1257. strcpy (abstracter, tok);
  1258. break;
  1259. case FIELDS:
  1260. tok = my_strtok ('\0', del_string);
  1261. while (tok != NULL) {
  1262. if (abstract_table == NULL) {
  1263. abstract_table = (struct key_id *) malloc
  1264. (sizeof (struct key_id));
  1265. abstract_current = abstract_table;
  1266. } else {
  1267. abstract_current->next =
  1268. (struct key_id *) malloc (
  1269. sizeof (struct key_id));
  1270. abstract_current = abstract_current->next;
  1271. }
  1272. strcpy (abstract_current->field_id, tok);
  1273. abstract_current->next = NULL;
  1274. tok = my_strtok ('\0', del_string);
  1275. }
  1276. break;
  1277. default:
  1278. BAD_ABSTR:
  1279. printf ( CATGETS(dtsearch_catd, MS_chandel, 47,
  1280. "Error line %d: Unknown option for abstract :'%s'\n"),
  1281. line_num, NULLORSTR(tok));
  1282. bad_profile = TRUE;
  1283. break;
  1284. } /* 'abstract' subswitch */
  1285. break;
  1286. default:
  1287. printf ( CATGETS(dtsearch_catd, MS_chandel, 48,
  1288. "Error line %d -unknown identifier type '%s'.\n") ,
  1289. line_num, NULLORSTR(tok));
  1290. bad_profile = TRUE;
  1291. break;
  1292. } /* main switch for each line in profile */
  1293. } while (TRUE); /* read-a-line do loop */
  1294. if (!date_pos_defined)
  1295. fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_chandel, 115,
  1296. "%s Default object dates will be '%s'.\n") ,
  1297. PROGNAME"1288", now_str);
  1298. if (bad_profile)
  1299. return;
  1300. /*---- Process tables, and check for identifiers referenced ----*/
  1301. if (!top_defined && !bot_defined) {
  1302. bad_profile = TRUE;
  1303. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 49,
  1304. "Error - delimiter not defined.\n") );
  1305. }
  1306. if (!key_defined) {
  1307. bad_profile = TRUE;
  1308. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 50,
  1309. "Error - key-type character never defined.\n") );
  1310. }
  1311. if (!key_pos_defined) {
  1312. bad_profile = TRUE;
  1313. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 51,
  1314. "Error - key never defined.\n") );
  1315. }
  1316. if (bad_profile)
  1317. return;
  1318. top_rec = NULL;
  1319. line_current = line_table;
  1320. while (line_current != NULL) {
  1321. if (strcmp (line_current->name, top_rec_name) == 0)
  1322. top_rec = line_current;
  1323. line_current = line_current->next;
  1324. }
  1325. if (top_rec_name[0] != 0 && top_rec == NULL) {
  1326. printf ( CATGETS(dtsearch_catd, MS_chandel, 52,
  1327. "Error - delimiter defined as '%s' was never found.\n") ,
  1328. top_rec_name);
  1329. bad_profile = TRUE;
  1330. } else if (strcmp (top_rec->head->text, line_mode) == 0) {
  1331. printf ( CATGETS(dtsearch_catd, MS_chandel, 53,
  1332. "Error - delimiter defined as '%s' references a physical "
  1333. "line in the record.\n Since the delimiter defines the "
  1334. "physical lines\n it cannot be referenced as a physical line.\n"),
  1335. top_rec_name);
  1336. bad_profile = TRUE;
  1337. }
  1338. field_current = field_table;
  1339. while (field_current != NULL) {
  1340. found = FALSE;
  1341. line_current = line_table;
  1342. while (line_current != NULL) {
  1343. if (!strcmp (field_current->line_id, line_current->name)) {
  1344. found = TRUE;
  1345. field_current->line = line_current;
  1346. }
  1347. line_current = line_current->next;
  1348. }
  1349. if (!found && !field_current->constant) {
  1350. printf ( CATGETS(dtsearch_catd, MS_chandel, 54,
  1351. "Error - for field '%s', no line identifier matches '%s'.\n") ,
  1352. field_current->name, field_current->line_id);
  1353. bad_profile = TRUE;
  1354. }
  1355. field_current = field_current->next;
  1356. }
  1357. finclude_current = finclude_tab;
  1358. while (finclude_current != NULL) {
  1359. /* find field, and set text_value */
  1360. field_current = field_table;
  1361. found = FALSE;
  1362. while (field_current != NULL) {
  1363. if (!strcmp (field_current->name, finclude_current->field_id)) {
  1364. field_current->text_action = finclude_current->value;
  1365. found = TRUE;
  1366. }
  1367. field_current = field_current->next;
  1368. }
  1369. if (!found) {
  1370. printf ( CATGETS(dtsearch_catd, MS_chandel, 55,
  1371. "Error - field include/exclude list included\n"
  1372. " the field '%s', which was never defined.\n") ,
  1373. finclude_current->field_id);
  1374. bad_profile = TRUE;
  1375. }
  1376. finclude_current = finclude_current->next;
  1377. }
  1378. i_i_current = i_i_t;
  1379. while (i_i_current != NULL) {
  1380. /* find line, and set text_action */
  1381. line_current = line_table;
  1382. found = FALSE;
  1383. while (line_current != NULL) {
  1384. if (!strcmp (line_current->name, i_i_current->line_id)) {
  1385. line_current->image_action = i_i_current->value;
  1386. found = TRUE;
  1387. }
  1388. line_current = line_current->next;
  1389. }
  1390. if (!found) {
  1391. printf ( CATGETS(dtsearch_catd, MS_chandel, 56,
  1392. "Error - image include/exclude list included\n"
  1393. " the line '%s', which was never defined.\n") ,
  1394. include_current->line_id);
  1395. bad_profile = TRUE;
  1396. }
  1397. i_i_current = i_i_current->next;
  1398. }
  1399. include_current = include_tab;
  1400. while (include_current != NULL) {
  1401. /* find line, and set text_action */
  1402. line_current = line_table;
  1403. found = FALSE;
  1404. while (line_current != NULL) {
  1405. if (!strcmp (line_current->name, include_current->line_id)) {
  1406. line_current->text_action = include_current->value;
  1407. found = TRUE;
  1408. }
  1409. line_current = line_current->next;
  1410. }
  1411. if (!found) {
  1412. printf ( CATGETS(dtsearch_catd, MS_chandel, 57,
  1413. "Error - text include/exclude list included\n"
  1414. " the line '%s', which was never defined.\n") ,
  1415. include_current->line_id);
  1416. bad_profile = TRUE;
  1417. }
  1418. include_current = include_current->next;
  1419. }
  1420. /* If "null" dates specified, no need to look for other date fields */
  1421. if (null_date_specified)
  1422. goto END_DATE_TABLE;
  1423. /* loop thru date table and link each field id to its structure */
  1424. for (date_current = date_table; date_current != NULL;
  1425. date_current = date_current->next) {
  1426. found = FALSE;
  1427. for (field_current = field_table; field_current != NULL;
  1428. field_current = field_current->next) {
  1429. if (strcmp (field_current->name, date_current->field_id) == 0) {
  1430. date_current->field = field_current;
  1431. found = TRUE;
  1432. break;
  1433. }
  1434. }
  1435. if (!found) {
  1436. printf ( CATGETS(dtsearch_catd, MS_chandel, 116,
  1437. "Error - date references undefined field '%s'.\n"),
  1438. date_current->field_id);
  1439. bad_profile = TRUE;
  1440. }
  1441. }
  1442. END_DATE_TABLE:
  1443. key_current = key_table;
  1444. while (key_current != NULL) {
  1445. field_current = field_table;
  1446. found = FALSE;
  1447. if (!strcmp ("time", key_current->field_id)) {
  1448. found = TRUE;
  1449. key_current->field = NULL;
  1450. } else if (!strcmp ("count", key_current->field_id)) {
  1451. found = TRUE;
  1452. key_current->field = NULL;
  1453. }
  1454. while (field_current != NULL) {
  1455. if (!strcmp (field_current->name, key_current->field_id)) {
  1456. found = TRUE;
  1457. key_current->field = field_current;
  1458. } else if (!strcmp ("time", key_current->field_id)) {
  1459. found = TRUE;
  1460. key_current->field = NULL;
  1461. } else if (!strcmp ("count", key_current->field_id)) {
  1462. found = TRUE;
  1463. key_current->field = NULL;
  1464. }
  1465. field_current = field_current->next;
  1466. }
  1467. if (!found) {
  1468. printf ( CATGETS(dtsearch_catd, MS_chandel, 58,
  1469. "Error - key definition references field '%s'\n"
  1470. " which was never defined.\n") ,
  1471. key_current->field_id);
  1472. bad_profile = TRUE;
  1473. }
  1474. key_current = key_current->next;
  1475. }
  1476. abstract_current = abstract_table;
  1477. while (abstract_current != NULL) {
  1478. field_current = field_table;
  1479. found = FALSE;
  1480. while (field_current != NULL) {
  1481. if (!strcmp (field_current->name, abstract_current->field_id)) {
  1482. found = TRUE;
  1483. abstract_current->field = field_current;
  1484. }
  1485. field_current = field_current->next;
  1486. }
  1487. if (!found) {
  1488. printf ( CATGETS(dtsearch_catd, MS_chandel, 59,
  1489. "Error - abstract definition references field '%s'\n"
  1490. " which was never defined.\n") ,
  1491. abstract_current->field_id);
  1492. bad_profile = TRUE;
  1493. }
  1494. abstract_current = abstract_current->next;
  1495. }
  1496. } /*--process_profile--*/
  1497. /**********************************************************************
  1498. CLEANUP - frees memory used by record
  1499. ***********************************************************************/
  1500. void cleanup (void)
  1501. {
  1502. struct line_id *line_current;
  1503. struct field_id *field_current;
  1504. struct rec *record;
  1505. /*-- Reset line_table --*/
  1506. line_current = line_table;
  1507. while (line_current != NULL) {
  1508. line_current->line = UNDEFINED;
  1509. line_current = line_current->next;
  1510. }
  1511. /*-- Reset field table --*/
  1512. field_current = field_table;
  1513. while (field_current != NULL) {
  1514. if (field_current->constant == FALSE)
  1515. field_current->value[0] = 0;
  1516. field_current = field_current->next;
  1517. }
  1518. /*-- clean up record, free memory for reuse --*/
  1519. record = record_head;
  1520. while (record_head != NULL) {
  1521. record_head = record->next;
  1522. free (record);
  1523. record = record_head;
  1524. }
  1525. }
  1526. /**************************************************************************
  1527. WRITE_RECORD - writes the final form of the record - key, fzkey, abstract,
  1528. and image.
  1529. **************************************************************************/
  1530. void write_record (void)
  1531. {
  1532. static int dotcount = 0;
  1533. char *ptr;
  1534. struct key_id *abst;
  1535. struct rec *record;
  1536. char value[200];
  1537. int lvalue;
  1538. int i;
  1539. int good = FALSE;
  1540. char buffer[200];
  1541. /* Line #1 is fzkey */
  1542. fprintf (outstream, " 0,2\n"); /* hardcoded null fzkey */
  1543. /* Line #2 is abstract */
  1544. value[0] = 0;
  1545. if (abstract == FIELDS) {
  1546. abst = abstract_table;
  1547. while (abst != NULL) {
  1548. strcat (value, abst->field->value);
  1549. abst = abst->next;
  1550. }
  1551. for (i = 0; i < strlen (value); i++)
  1552. if (value[i] == '\n')
  1553. value[i] = ' ';
  1554. }
  1555. fprintf (outstream, "ABSTRACT: %s\n", value);
  1556. /* Line #3 is unique database key */
  1557. if (key_value[strlen (key_value) - 1] == '\n')
  1558. key_value[strlen (key_value) - 1] = 0;
  1559. if (uppercase)
  1560. strupr (key_value);
  1561. fprintf (outstream, "%c%s\n", key_char, key_value);
  1562. /* Line #4 is object date in objdate string format.
  1563. * Prior to version 2.0.8 this would be the first line of text.
  1564. */
  1565. if (null_date_specified)
  1566. fputs (NULLDATESTR"\n", outstream);
  1567. else
  1568. fprintf (outstream, "%s\n",
  1569. objdate2fzkstr (tm2objdate (objdate_tmptr)));
  1570. /* Lines #5 and thereafter (text) of .fzk rec */
  1571. record = record_head;
  1572. while (record != NULL) {
  1573. /*
  1574. * Strip out any control-l's, as we put our own later,
  1575. * and any extras might freak out something that wants
  1576. * a control-l as a delimeter.
  1577. */
  1578. for (i = 0; i < strlen (record->text); i++)
  1579. if (record->text[i] == CNTRL_L)
  1580. record->text[i] = ' ';
  1581. lvalue = (record->line)? record->line->image_action : 0;
  1582. switch (lvalue) {
  1583. case CLEAR:
  1584. imageflag = INCLUDE;
  1585. break;
  1586. case SET:
  1587. imageflag = EXCLUDE;
  1588. break;
  1589. default:
  1590. break;
  1591. }
  1592. if ((imageflag == INCLUDE && lvalue != EXCLUDE)
  1593. || (lvalue == INCLUDE)) {
  1594. /* trim to fit in screen */
  1595. strcpy (buffer, record->text);
  1596. if (strlen (buffer) > screen_width) {
  1597. buffer[screen_width] = '\n';
  1598. buffer[screen_width + 1] = 0;
  1599. }
  1600. fprintf (outstream, "%s", buffer);
  1601. }
  1602. record = record->next;
  1603. if (lvalue == DEFAULT)
  1604. imageflag = imagemode;
  1605. }
  1606. /* Test final record write to check for full filesystem */
  1607. if (fprintf (outstream, "%c\n", CNTRL_L) <= 0) {
  1608. printf ( CATGETS(dtsearch_catd, MS_chandel, 124,
  1609. "%s Unable to write to output file '%s':\n %s\n") ,
  1610. PROGNAME"1663", outfile, strerror(errno));
  1611. DtSearchExit (2);
  1612. }
  1613. return;
  1614. } /* write_record */
  1615. /************************************************/
  1616. /* */
  1617. /* mmm_to_digits */
  1618. /* */
  1619. /************************************************/
  1620. /* Translates a field value which is a recognizable month
  1621. * name string into a two-char digit string from "01" to "12".
  1622. */
  1623. static void mmm_to_digits (struct field_id *fld)
  1624. {
  1625. static char valbuf[8];
  1626. static char *months = NULL;
  1627. int i;
  1628. if (months == NULL)
  1629. months = strdup (CATGETS(dtsearch_catd, MS_chandel, 125,
  1630. "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"));
  1631. for (i=0; i<3; i++)
  1632. valbuf[i] = toupper (fld->value[i]);
  1633. for (i=0; i<12; i++)
  1634. if (strncmp (valbuf, months + (i*3), 3) == 0) {
  1635. sprintf (fld->value, "%02d", ++i);
  1636. break;
  1637. }
  1638. return;
  1639. } /* mmm_to_digits() */
  1640. /************************************************/
  1641. /* */
  1642. /* process_record */
  1643. /* */
  1644. /************************************************/
  1645. /* PROCESS_RECORD - does all processing for the record currently stored
  1646. * in the data structure pointed to by record_head. If record_head points
  1647. * to NULL, it can safely be assumed that no record is currently awaiting
  1648. * processing.
  1649. */
  1650. void process_record (void)
  1651. {
  1652. struct field_id
  1653. *field_current;
  1654. struct key_id
  1655. *key_current;
  1656. struct date_id
  1657. *date_current;
  1658. struct rec *record;
  1659. char *pos;
  1660. char value[200];
  1661. int lvalue;
  1662. int i;
  1663. int linelen;
  1664. char date_value[256];
  1665. int dummy;
  1666. int meaningless;
  1667. static int dotcount = 0;
  1668. if (record_head == NULL)
  1669. return;
  1670. /* Print progress dots and messages */
  1671. rec_count++;
  1672. if (rec_count % RECS_PER_DOT == 0L) {
  1673. putchar('.');
  1674. if (++dotcount % 10 == 0)
  1675. putchar(' ');
  1676. if (dotcount % 50 == 0) {
  1677. putchar('\n');
  1678. dotcount = 0;
  1679. }
  1680. fflush(stdout);
  1681. }
  1682. discard_record = FALSE;
  1683. meaningless = FALSE;
  1684. /* Main loop on every line in record */
  1685. record = record_head;
  1686. while (record != NULL) {
  1687. lvalue = (record->line)? record->line->text_action : 0;
  1688. switch (lvalue) {
  1689. case CLEAR:
  1690. textflag = INCLUDE;
  1691. break;
  1692. case SET:
  1693. textflag = EXCLUDE;
  1694. break;
  1695. default:
  1696. break;
  1697. } /* switch */
  1698. field_current = field_table;
  1699. while (field_current != NULL) {
  1700. if (field_current->line == record->line) {
  1701. /* this field is defined within this line */
  1702. memset (value, 0, sizeof(value));
  1703. /* If profile pattern str was empty ("") ...*/
  1704. if (field_current->text[0] == 0) {
  1705. if (field_current->defined_length == EOLN)
  1706. strncpy (value, record->text +
  1707. (field_current->offset - 1), sizeof(value)-1);
  1708. else if (field_current->defined_length == EOW)
  1709. /* copy until end of word only */
  1710. for (dummy = 0;
  1711. (!isspace ((record->text +
  1712. (field_current->offset - 1))[dummy]))
  1713. && dummy < sizeof(value);
  1714. dummy++
  1715. )
  1716. value[dummy] = (record->text +
  1717. (field_current->offset - 1))[dummy];
  1718. else {
  1719. i = (field_current->defined_length < sizeof(value))?
  1720. field_current->defined_length : sizeof(value)-1;
  1721. strncpy (value,
  1722. record->text + (field_current->offset - 1),
  1723. i);
  1724. }
  1725. }
  1726. /* ...else if profile pattern str was not empty ("xxx") */
  1727. else {
  1728. pos = strstr (record->text, field_current->text);
  1729. if (pos != NULL) { /* pattern found... */
  1730. if (field_current->defined_length == EOLN)
  1731. strncpy (value,
  1732. pos + (field_current->offset - 1),
  1733. sizeof(value) - 1);
  1734. else if (field_current->defined_length == EOW)
  1735. /* copy until end of word only */
  1736. for (dummy = 0;
  1737. (!isspace ((pos +
  1738. (field_current->offset - 1))[dummy]))
  1739. && dummy < sizeof(value);
  1740. dummy++
  1741. )
  1742. value[dummy] = (pos +
  1743. (field_current->offset - 1))[dummy];
  1744. else {
  1745. i = (field_current->defined_length<sizeof(value))?
  1746. field_current->defined_length : sizeof(value)-1;
  1747. strncpy (value,
  1748. pos + (field_current->offset - 1),
  1749. i);
  1750. }
  1751. } /* end pattern found */
  1752. } /* end else where pattern str not empty */
  1753. /* strip \n's out of value */
  1754. for (i = 0; i < strlen (value); i++)
  1755. if (value[i] == '\n')
  1756. value[i] = 0;
  1757. if (field_current->constant == FALSE) {
  1758. strncpy (field_current->value, value,
  1759. sizeof(field_current->value));
  1760. field_current->value [sizeof(field_current->value)-1] = 0;
  1761. field_current->length = strlen (field_current->value);
  1762. if (field_current->is_month)
  1763. mmm_to_digits (field_current);
  1764. }
  1765. }
  1766. field_current = field_current->next;
  1767. } /* end while loop on each field within each line */
  1768. if (lvalue == DEFAULT)
  1769. textflag = textmode;
  1770. record = record->next;
  1771. } /* end while loop on each record line */
  1772. /* Build a handel date_value string from specified fields.
  1773. * If 'date' was not specified, uses current date/time.
  1774. * If 'date = null' was specified, uses special constant string.
  1775. * If value error in specified date fields,
  1776. * uses current date/time and prints err msg.
  1777. */
  1778. objdate_tmptr = &nowtm; /* default */
  1779. if (date_pos_defined && !null_date_specified) {
  1780. date_value[0] = 0;
  1781. for (date_current = date_table; date_current != NULL;
  1782. date_current = date_current->next) {
  1783. if (date_current->field->value[0] != 0) {
  1784. strcat (date_value, date_current->field->value);
  1785. }
  1786. else {
  1787. date_value[0] = 0; /* flags error msg */
  1788. break;
  1789. }
  1790. }
  1791. /*
  1792. * Validate format for date_value of this record.
  1793. * Date value format: YYYYMMDDhhmm (exactly 12 digits).
  1794. * The area at date_value + 100 is just a little atoi buffer.
  1795. */
  1796. if (date_value[0] == 0)
  1797. goto BAD_DATE_VALUE;
  1798. if (strlen (date_value) != 12)
  1799. goto BAD_DATE_VALUE;
  1800. for (i = 0; i < 12; i++)
  1801. if (!isdigit (date_value[i]))
  1802. goto BAD_DATE_VALUE;
  1803. /* year = YYYY */
  1804. strncpy (date_value + 100, date_value, 4);
  1805. date_value[104] = 0;
  1806. i = atoi (date_value + 100);
  1807. if (i < 1900 || i > 5995) /* valid OBJDATE years */
  1808. goto BAD_DATE_VALUE;
  1809. else
  1810. rectm.tm_year = i - 1900;
  1811. /* month = MM */
  1812. strncpy (date_value + 100, date_value + 4, 2);
  1813. date_value[102] = 0;
  1814. i = atoi (date_value + 100);
  1815. if (i < 1 || i > 12)
  1816. goto BAD_DATE_VALUE;
  1817. else
  1818. rectm.tm_mon = i - 1; /* tm values = 0 - 11 */
  1819. /* day = DD */
  1820. strncpy (date_value + 100, date_value + 6, 2);
  1821. date_value[102] = 0;
  1822. i = atoi (date_value + 100);
  1823. if (i < 1 || i > 31)
  1824. goto BAD_DATE_VALUE;
  1825. else
  1826. rectm.tm_mday = i;
  1827. /* hours = hh */
  1828. strncpy (date_value + 100, date_value + 8, 2);
  1829. date_value[102] = 0;
  1830. i = atoi (date_value + 100);
  1831. if (i < 0 || i > 23)
  1832. goto BAD_DATE_VALUE;
  1833. else
  1834. rectm.tm_hour = i;
  1835. /* minutes = mm */
  1836. strncpy (date_value + 100, date_value + 10, 2);
  1837. date_value[102] = 0;
  1838. i = atoi (date_value + 100);
  1839. if (i < 0 || i > 59)
  1840. goto BAD_DATE_VALUE;
  1841. else
  1842. rectm.tm_min = i;
  1843. objdate_tmptr = &rectm;
  1844. goto GOOD_DATE_VALUE;
  1845. BAD_DATE_VALUE:
  1846. objdate_tmptr = &nowtm;
  1847. printf ( CATGETS(dtsearch_catd, MS_chandel, 133,
  1848. "Warning - '%s' is invalid date specification.\n"
  1849. " Using '%s' date for record number %ld that began: %.30s\n") ,
  1850. date_value, now_str, rec_count, record_head->text);
  1851. GOOD_DATE_VALUE:
  1852. ;
  1853. } /* end if (date_pos_defined) */
  1854. key_current = key_table;
  1855. key_count++;
  1856. for (dummy = 0; dummy < 80; dummy++)
  1857. key_value[dummy] = 0;
  1858. dummy = FALSE;
  1859. while (key_current != NULL) {
  1860. if (key_current->field == NULL) {
  1861. if (strcmp (key_current->field_id, "time") == 0)
  1862. sprintf (key_value, "%ld%06ld", now, key_count);
  1863. else /* must be 'count' */
  1864. sprintf (key_value, "%09ld", key_count);
  1865. } else if (key_current->field->value[0] != 0) {
  1866. strcat (key_value, key_current->field->value);
  1867. } else {
  1868. dummy = TRUE;
  1869. }
  1870. key_current = key_current->next;
  1871. }
  1872. if (dummy && warnings) {
  1873. printf ( CATGETS(dtsearch_catd, MS_chandel, 68,
  1874. "Warning - fields necessary for key not found.\n"
  1875. " discarding record #%ld that began:\n %s\n") ,
  1876. rec_count, record_head->text);
  1877. } else if (discard && meaningless && warnings) {
  1878. printf ( CATGETS(dtsearch_catd, MS_chandel, 69,
  1879. "Warning - record #ld deemed meaningless, discarding...\n"
  1880. " record began: %.60s\n") ,
  1881. rec_count, record_head->text);
  1882. } else {
  1883. outcount++;
  1884. write_record ();
  1885. }
  1886. cleanup ();
  1887. } /*--process_record--*/
  1888. /**************************************************************************
  1889. NEW_REC - determines if the string sent represents a new record or
  1890. not.
  1891. **************************************************************************/
  1892. int new_rec (char *buffer)
  1893. {
  1894. int cant_be = FALSE;
  1895. top_rec->comp = top_rec->head;
  1896. while (top_rec->comp != NULL) {
  1897. if (strcmp (top_rec->comp->text, line_mode) != 0) {
  1898. if (top_rec->comp->column_number == ANY) {
  1899. if (strstr(buffer,top_rec->comp->text)==NULL)
  1900. cant_be = TRUE;
  1901. }
  1902. /* if */
  1903. else if (strncmp (buffer + (top_rec->comp->column_number - 1),
  1904. top_rec->comp->text,
  1905. strlen (top_rec->comp->text)) != 0)
  1906. cant_be = TRUE;
  1907. } /* if */
  1908. top_rec->comp = top_rec->comp->next;
  1909. } /* while */
  1910. if (cant_be == FALSE) {
  1911. return TRUE;
  1912. } else
  1913. return FALSE;
  1914. } /*--new_rec--*/
  1915. /**************************************************************************
  1916. IS_WHITESPACE - returns true if the string passed contains only
  1917. whitespace
  1918. **************************************************************************/
  1919. int is_whitespace (char *s)
  1920. {
  1921. int i;
  1922. for (i = 0; i < strlen (s); i++)
  1923. if (!isspace (s[i]) || s[i] == 12)
  1924. return FALSE;
  1925. return TRUE;
  1926. }
  1927. /**************************************************************************
  1928. PROCESS_INFILE - processes the input file, 1 record at a time. For each
  1929. record, the lines must first be compared against the line id's we have, to
  1930. try and identify each line. Then fields are processed against these lines,
  1931. and finally fzk processing can begin on any lines that are indicated being
  1932. important.
  1933. ***************************************************************************/
  1934. void process_infile (void)
  1935. {
  1936. int line_num = 0;
  1937. struct line_id *line_current;
  1938. struct rec *record = NULL;
  1939. char buffer[200];
  1940. int cant_be;
  1941. time_t startime = 0L;
  1942. int i;
  1943. int rc;
  1944. if (!strcmp (infile, "-"))
  1945. instream = stdin;
  1946. else {
  1947. if ((instream = fopen (infile, "rt")) == NULL) {
  1948. printf ( CATGETS(dtsearch_catd, MS_chandel, 70,
  1949. " Unable to open input file '%s'.\n") , infile);
  1950. exit (FILE_ERROR);
  1951. }
  1952. }
  1953. record_head = NULL;
  1954. time (&startime);
  1955. while (fgets (buffer, sizeof (buffer) - 1, instream) != NULL) {
  1956. /* clean any non ASCII characters out of buffer */
  1957. delete_whitespace (buffer);
  1958. if (feof (instream))
  1959. continue; /*-* end of file *-*/
  1960. if (del_blanklines && is_whitespace (buffer))
  1961. continue;
  1962. if (new_rec (buffer)) {
  1963. if (bot_defined) {
  1964. if (record_head == NULL) {
  1965. record_head = (struct rec *) malloc (sizeof (struct rec));
  1966. record = record_head;
  1967. } else {
  1968. record->next = (struct rec *) malloc (sizeof (struct rec));
  1969. record = record->next;
  1970. }
  1971. record->next = NULL;
  1972. line_num++;
  1973. record->line_num = line_num;
  1974. strcpy (record->text, buffer);
  1975. record->line = NULL;
  1976. /*-- search list of line_id's for a possible match --*/
  1977. line_current = line_table;
  1978. while (line_current != NULL) {
  1979. cant_be = FALSE;
  1980. line_current->comp = line_current->head;
  1981. while (line_current->comp != NULL) {
  1982. if (strcmp (line_current->comp->text, line_mode) != 0) {
  1983. if (line_current->comp->column_number == ANY) {
  1984. if (strstr(buffer,line_current->comp->text)
  1985. == NULL)
  1986. cant_be = TRUE;
  1987. } else if (
  1988. strncmp (buffer +
  1989. (line_current->comp->column_number - 1),
  1990. line_current->comp->text,
  1991. strlen (line_current->comp->text)) != 0)
  1992. cant_be = TRUE;
  1993. } else if (line_current->comp->column_number
  1994. != line_num)
  1995. cant_be = TRUE;
  1996. line_current->comp = line_current->comp->next;
  1997. }
  1998. if (cant_be == FALSE) {
  1999. /* found a hit, set pointers */
  2000. line_current->line = record;
  2001. record->line = line_current;
  2002. } /* if */
  2003. line_current = line_current->next;
  2004. } /* while - line_current loop */
  2005. } /* if bot_defined */
  2006. process_record ();
  2007. if (shutdown_now)
  2008. break;
  2009. line_num = 0;
  2010. started = TRUE;
  2011. if (bot_defined)
  2012. continue;
  2013. }
  2014. if (record_head == NULL) {
  2015. record_head = (struct rec *) malloc (sizeof (struct rec));
  2016. record = record_head;
  2017. } else {
  2018. record->next = (struct rec *) malloc (sizeof (struct rec));
  2019. record = record->next;
  2020. }
  2021. record->next = NULL;
  2022. line_num++;
  2023. record->line_num = line_num;
  2024. strcpy (record->text, buffer);
  2025. record->line = NULL;
  2026. /*-- search list of line_id's for a possible match --*/
  2027. line_current = line_table;
  2028. while (line_current != NULL) {
  2029. cant_be = FALSE;
  2030. line_current->comp = line_current->head;
  2031. while (line_current->comp != NULL) {
  2032. if (strcmp (line_current->comp->text, line_mode) != 0) {
  2033. if (line_current->comp->column_number == ANY) {
  2034. if (strstr(buffer,line_current->comp->text)==NULL){
  2035. cant_be = TRUE;
  2036. }
  2037. } else if (strncmp (buffer +
  2038. (line_current->comp->column_number - 1),
  2039. line_current->comp->text,
  2040. strlen (line_current->comp->text)) != 0) {
  2041. cant_be = TRUE;
  2042. }
  2043. } else if (line_current->comp->column_number != line_num) {
  2044. cant_be = TRUE;
  2045. }
  2046. line_current->comp = line_current->comp->next;
  2047. }
  2048. if (cant_be == FALSE) {
  2049. /* found a hit, set pointers */
  2050. line_current->line = record;
  2051. record->line = line_current;
  2052. } /* if */
  2053. line_current = line_current->next;
  2054. } /* while - line_current loop */
  2055. for (rc = 0; rc < 200; rc++)
  2056. buffer[rc] = 0;
  2057. } /* while - buffer read loop */
  2058. /*- check for any leftover records -*/
  2059. process_record ();
  2060. } /*-- process_infile --*/
  2061. /************************************************/
  2062. /* */
  2063. /* usage_msg */
  2064. /* */
  2065. /************************************************/
  2066. static void usage_msg (void)
  2067. {
  2068. static char *default_text =
  2069. "\nUSAGE: %s [options] <profile> <infile> [<outfile>]\n"
  2070. " -m Turn off all but error messages.\n"
  2071. " -wN Change target screen width to <N>.\n"
  2072. " -oo Preapprove overwrite of outfile.\n"
  2073. " -oa Preapprove append to outfile.\n"
  2074. " <profile> Input file containing profile of records\n"
  2075. " to be processed.\n"
  2076. " <infile> Input file containing actual records.\n"
  2077. " <outfile> Output file name, .fzk format (%s).\n\n";
  2078. if (!warnings)
  2079. return;
  2080. printf (CATGETS(dtsearch_catd, MS_chandel, 71, default_text),
  2081. aa_argv0, EXT_FZKEY);
  2082. return;
  2083. } /* usage_msg() */
  2084. /************************************************/
  2085. /* */
  2086. /* user_arg_processor */
  2087. /* */
  2088. /************************************************/
  2089. /* Process any user arguments passed thru the command line parameters. */
  2090. static void user_arg_processor (int argc, char **argv)
  2091. {
  2092. char *cptr, *argptr;
  2093. char *pos;
  2094. if (argc <= 1) {
  2095. bad_parm = TRUE;
  2096. return;
  2097. } /* if */
  2098. while (--argc > 0 && (*++argv)[0] == '-') {
  2099. argptr = argv[0];
  2100. argptr[1] = tolower (argptr[1]);
  2101. switch (argptr[1]) {
  2102. case 'w':
  2103. if ((screen_width = atoi (argptr + 2)) == 0) {
  2104. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 72,
  2105. "Invalid screen width specified.\n") );
  2106. bad_parm = TRUE;
  2107. }
  2108. break;
  2109. case 'm':
  2110. warnings = FALSE;
  2111. break;
  2112. case 'o':
  2113. argptr[2] = tolower (argptr[2]);
  2114. if (argptr[2] == 'o')
  2115. strcpy (outmode, "w");
  2116. else if (argptr[2] == 'a')
  2117. strcpy (outmode, "a");
  2118. else {
  2119. printf ( CATGETS(dtsearch_catd, MS_chandel, 75,
  2120. "'%s' is invalid output mode.\n") , argptr);
  2121. bad_parm = TRUE;
  2122. } /* else */
  2123. outmode_specified = TRUE;
  2124. break;
  2125. default:
  2126. printf ( CATGETS(dtsearch_catd, MS_chandel, 76,
  2127. "Unknown command line argument '%s'.\n") , argptr);
  2128. bad_parm = TRUE;
  2129. } /*--switch--*/
  2130. } /*--while--*/
  2131. if (argc-- <= 0) {
  2132. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 77,
  2133. "Missing required profile-file name.\n") );
  2134. bad_parm = TRUE;
  2135. }
  2136. /* if */
  2137. else {
  2138. /******
  2139. strcpy(profile,argv[0]);
  2140. profile=argv[0];
  2141. *******/
  2142. profile = (char *) malloc (sizeof (char) * (strlen (argv[0])) +10);
  2143. strcpy (profile, argv[0]);
  2144. if (strchr (profile, '.') == NULL)
  2145. strcat (profile, EXT_HANDEL);
  2146. }
  2147. if (argc-- <= 0) {
  2148. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 78,
  2149. "Missing required input-file name.\n") );
  2150. bad_parm = TRUE;
  2151. }
  2152. /* if */
  2153. else
  2154. /******** strcpy(infile,argv[1]); ********/
  2155. infile = argv[1];
  2156. if (argc-- <= 0) {
  2157. /*****************
  2158. strcpy(outfile,infile);
  2159. if (strchr(outfile,'.')!=NULL)
  2160. strcpy(strchr(outfile,'.'), EXT_FZKEY);
  2161. else
  2162. strcat(outfile,EXT_FZKEY);
  2163. *****************/
  2164. if (strcmp (infile, "-") == 0) {
  2165. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 79, "Error - using "
  2166. "stdin as input, output filename is required!\n") );
  2167. exit (FILE_ERROR);
  2168. } else {
  2169. outfile = (char *) malloc (sizeof (char) * (strlen (infile) + 10));
  2170. strcpy (outfile, infile);
  2171. pos = strrchr (outfile, (int) '.');
  2172. if (pos == NULL)
  2173. strcat (outfile, EXT_FZKEY);
  2174. else {
  2175. pos++;
  2176. pos[0] = 'f';
  2177. pos++;
  2178. pos[0] = 'z';
  2179. pos++;
  2180. pos[0] = 'k';
  2181. pos++;
  2182. pos[0] = 0;
  2183. }
  2184. }
  2185. }
  2186. /* if */
  2187. else
  2188. /* strcpy(outfile,argv[2]); */
  2189. outfile = argv[2];
  2190. /*-- Sanity checks --*/
  2191. /*-- duplicates? --*/
  2192. if (strcmp (infile, profile) == 0) {
  2193. printf ( CATGETS(dtsearch_catd, MS_chandel, 80,
  2194. "Profile file and input file have same name:'%s'.\n") ,
  2195. infile);
  2196. bad_parm = TRUE;
  2197. } /* if */
  2198. if (strcmp (infile, outfile) == 0 && strcmp (infile, "-")) {
  2199. printf ( CATGETS(dtsearch_catd, MS_chandel, 81,
  2200. "Input file and output file have same name:'%s'.\n") ,
  2201. infile);
  2202. bad_parm = TRUE;
  2203. } /* if */
  2204. if (strcmp (profile, outfile) == 0) {
  2205. printf ( CATGETS(dtsearch_catd, MS_chandel, 82,
  2206. "Profile file and output file have same name:'%s'.\n") ,
  2207. profile);
  2208. bad_parm = TRUE;
  2209. } /* if */
  2210. if(warnings)
  2211. {
  2212. printf ( CATGETS(dtsearch_catd, MS_chandel, 83,
  2213. " Profile file: %s\n") , profile);
  2214. if (strcmp (infile, "-") == 0)
  2215. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 84,
  2216. " Input file: stdin\n") );
  2217. else
  2218. printf ( CATGETS(dtsearch_catd, MS_chandel, 85,
  2219. " Input file: %s\n") , infile);
  2220. if (strcmp (outfile, "-") == 0)
  2221. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 86,
  2222. " Output file: stdout\n") );
  2223. else
  2224. printf ( CATGETS(dtsearch_catd, MS_chandel, 87,
  2225. " Output file: %s\n") , outfile);
  2226. }
  2227. } /*--user_args_processor--*/
  2228. /****************************************************************************
  2229. FLAG_SHUTDOWN - signal handler - to allow for graceful exiting
  2230. ****************************************************************************/
  2231. static void flag_shutdown (int sig)
  2232. {
  2233. shutdown_now = TRUE;
  2234. }
  2235. /****************************************************************************
  2236. MAIN - Body of Handel. Checks user parameters, processes the profile
  2237. file, and then goes into the main loop, running each record from the input
  2238. file against the profile and thru the text processor.
  2239. *****************************************************************************/
  2240. int main (int argc, char **argv)
  2241. {
  2242. int oops;
  2243. /*-- Initialization --*/
  2244. aa_argv0 = argv[0];
  2245. setlocale (LC_ALL, "");
  2246. dtsearch_catd = CATOPEN(FNAME_DTSRCAT, 0);
  2247. printf ( CATGETS(dtsearch_catd, MS_chandel, 88,
  2248. "%s. %s %s Text Filter.\n") ,
  2249. aa_argv0, PRODNAME, DtSrVERSION);
  2250. time (&now);
  2251. memcpy (&nowtm, localtime(&now), sizeof(struct tm));
  2252. strftime (now_str, sizeof(now_str), "%y/%m/%d~%H:%M", &nowtm);
  2253. memset (&rectm, 0, sizeof(struct tm));
  2254. /* check user arguments */
  2255. user_arg_processor (argc, argv);
  2256. if (bad_parm) {
  2257. usage_msg ();
  2258. exit (USAGE);
  2259. }
  2260. process_profile ();
  2261. if (warnings && !bad_profile) {
  2262. signal (SIGINT, flag_shutdown);
  2263. signal (SIGTERM, flag_shutdown);
  2264. open_outfile ();
  2265. printf ( CATGETS(dtsearch_catd, MS_chandel, 89,
  2266. "\nInterrupt with CTRL-C to exit gracefully "
  2267. "at record boundary.\n Each dot is %ld records...\n"),
  2268. RECS_PER_DOT);
  2269. process_infile (); /* process the input file */
  2270. oops = fclose (outstream);
  2271. fclose (instream);
  2272. if (oops < 0) {
  2273. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 90,
  2274. "\nError closing output file - disk full?\n") );
  2275. exit (FILE_ERROR);
  2276. }
  2277. }
  2278. else {
  2279. printf ( "%s", CATGETS(dtsearch_catd, MS_chandel, 91,
  2280. "Quitting due to errors in profile file.\n") );
  2281. exit (BAD_PROFILE);
  2282. }
  2283. printf ( CATGETS(dtsearch_catd, MS_chandel, 92,
  2284. "\n%s: Normal completion. %ld records processed. Exit code = 0.\n"),
  2285. aa_argv0, rec_count);
  2286. return 0;
  2287. }
  2288. /*************** DTSRHAN.C ****************/