123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- * COMPONENT_NAME: austext
- *
- * FUNCTIONS: browser
- * change_database
- * deleter
- * kill_delete
- * load_dbatab
- * main
- * parse_infbuf
- * print_exit_code
- * retncode_abort
- *
- * ORIGINS: 27
- *
- * (C) COPYRIGHT International Business Machines Corp. 1992,1995
- * All Rights Reserved
- * US Government Users Restricted Rights - Use, duplication or
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- /******************* TOMITA.C *******************
- * $TOG: tomita.c /main/9 1998/04/17 11:23:38 mgreess $
- * May 1992.
- * Replaces original tomita but removes curses dependencies
- * and uses Opera Engine for deletes rather than hard
- * coding vista calls.
- *
- * In effect, tomita is two programs.
- * Program #1 browses an input list of opera record ids and
- * prompts user to confirm that they should be deleted from opera.
- * The confirmed list is written to an output file that is identical in format.
- * Program 1 can be run anytime because it only reads the database.
- *
- * Program #2 deletes record from an input list, presumably
- * the output of program #1. Program #2 writes to vista and changes it.
- * It MUST be run offline when no users are logged into opera,
- * in order to prevent database corruption.
- * Currently password is passed on command line.
- * The password is maintained in an encrypted flat file.
- * It can be changed from an undocumented Opera Engine function
- * available in tuiopera.
- *
- * RECORD ID FILE FORMAT (shdscrd.lst format):
- * One record to be deleted per line.
- * 3 words per line separated by whitespace, everything thereafter is comments.
- * (These programs only use the first 2 words).
- * All words may be optionally enclosed in double quotes
- * to capture embedded blanks ("xxx xxx").
- * ...
- * databasename recordid userid comments...\n
- * ...
- *
- * $Log$
- * Revision 2.2 1995/10/25 15:21:36 miker
- * Added prolog.
- *
- * Revision 2.1 1995/09/22 22:17:11 miker
- * Freeze DtSearch 0.1, AusText 2.1.8
- *
- * Revision 1.11 1995/09/05 19:14:39 miker
- * Removed password requirement. DtSearch header file and function
- * name changes. Made usrblk universal global.
- */
- #include "SearchE.h"
- #include <string.h>
- #include <ctype.h>
- #include <signal.h>
- #include <sys/stat.h>
- #include <locale.h>
- #include <stdlib.h>
- #define PRINT_MESSAGES \
- { puts (DtSearchGetMessages()); DtSearchFreeMessages(); }
- #define TOKEN_DELIM " \t\n"
- #define PAUSE_ROWS 15
- #define DBACOUNT 2000
- #define PROGNAME "TOMITA"
- #define MS_tomita 29
- #define MS_misc 1
- /*------------------ GLOBALS ------------------*/
- static int debug_mode = FALSE;
- static int prog = 'B'; /* 'D' = deleting, 'B' = browsing */
- static int shutdown_now = FALSE;
- static int yesarg = FALSE;
- static int retncode = 0;
- static int max_dbacount = DBACOUNT;
- static FILE *inf, *outf;
- static char *infname;
- static char *outfname;
- static long maxtime;
- static long records_read;
- static char parsed_dbname [24];
- static DBLK *parsed_dblk;
- char parsed_recid [2048];
- /************************************************/
- /* */
- /* print_exit_code */
- /* */
- /************************************************/
- /* Called from inside DtSearchExit() at austext_exit_last */
- static void print_exit_code (int exit_code)
- {
- printf ( CATGETS(dtsearch_catd, MS_tomita, 3,
- "%s: Exit Code = %d.\n") ,
- aa_argv0, exit_code);
- return;
- } /* print_exit_code() */
- /************************************************/
- /* */
- /* kill_delete */
- /* */
- /************************************************/
- /* Interrupt handler for all termination signals
- * in Delete mode. Just sets global flag so we
- * can come down gracefully between deletions.
- */
- static void kill_delete (int sig)
- {
- shutdown_now = TRUE;
- printf ( CATGETS(dtsearch_catd, MS_tomita, 1,
- "\n%s Received interrupt %d.\n"
- " Program will stop after current batch of deletions.\n") ,
- PROGNAME"069", sig);
- return;
- } /* kill_delete() */
- /************************************************/
- /* */
- /* retncode_abort */
- /* */
- /************************************************/
- static void retncode_abort (int location)
- {
- fputc ('\n', aa_stderr);
- if (DtSearchHasMessages ())
- fprintf (aa_stderr, "%s\n", DtSearchGetMessages ());
- fprintf (aa_stderr,
- PROGNAME "%d Program abort. usrblk.retncode = %d. Exit code = 3.\n",
- location, usrblk.retncode);
- DtSearchExit (3);
- } /* retncode_abort() */
- /****************************************/
- /* */
- /* change_database */
- /* */
- /****************************************/
- /* Changes usrblk.dblk to point to passed database name.
- * Returns TRUE if successful.
- */
- static int change_database (char *newname)
- {
- DBLK *db;
- for (db = usrblk.dblist; db != NULL; db = db->link)
- if (strcmp (db->name, newname) == 0) {
- usrblk.dblk = db;
- return TRUE;
- }
- /* Invalid newname. If deleting, just say which database is invalid. */
- retncode = 1;
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 4,
- "%s Database '%s' not found.\n") ,
- PROGNAME"114", newname);
- if (prog == 'D')
- return FALSE;
- /* If browsing, tell user his options */
- fprintf (aa_stderr, "%s", CATGETS(dtsearch_catd, MS_tomita, 5,
- "Available choices are:") );
- for (db = usrblk.dblist; db != NULL; db = db->link)
- fprintf (aa_stderr, " '%s'", db->name);
- fputc ('\n', aa_stderr);
- return FALSE;
- } /* change_database() */
- /****************************************/
- /* */
- /* parse_infbuf */
- /* */
- /****************************************/
- /* Parses a line from a standard formatted discard file.
- * If first word indicates different database from usrblk.dblk,
- * changes it. First token loaded into parsed_dbname
- * (and parsed_dblk will be made to track it), and
- * second token is loaded into parsed_recid.
- * Tokens are separated by blanks and/or tabs,
- * except 2nd token may have embedded spaces if it is
- * surrounded by double quotes. Returns TRUE unless
- * database couldn't change or other error, then returns FALSE.
- */
- static int parse_infbuf (char *infbuf)
- {
- char *ptr;
- char mybuf[1024];
- /* Do all parsing in my own buf so infbuf not peppered with \0's */
- strncpy (mybuf, infbuf, sizeof (mybuf));
- mybuf[sizeof (mybuf) - 1] = 0;
- /* Parse first token (database name) */
- if ((ptr = strtok (mybuf, " \t")) == NULL) {
- /* Msg #8 is used in two places */
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 8,
- "%s Invalid input format: %.30s...\n") ,
- PROGNAME"152", infbuf);
- retncode = 1;
- return FALSE;
- }
- /* Change database if necessary */
- if (strcmp (ptr, usrblk.dblk->name) != 0)
- if (!change_database (ptr)) {
- retncode = 1;
- return FALSE;
- }
- snprintf(parsed_dbname, sizeof(parsed_dbname), "%s", ptr);
- parsed_dblk = usrblk.dblk;
- /* Hop over to beginning of 2nd token */
- for (ptr += strlen (ptr) + 1; *ptr == ' ' || *ptr == '\t'; ptr++);
- /* Get 2nd token (record id). Token delimiters depend
- * on whether token begins with a double quote.
- */
- ptr = strtok (ptr, (*ptr == '\"') ? "\"" : " \t");
- if (ptr == NULL) {
- /* Msg #8 is used in two places */
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 8,
- "%s Invalid input format: %.30s...\n") ,
- PROGNAME"176", infbuf);
- retncode = 1;
- return FALSE;
- }
- strncpy (parsed_recid, ptr, sizeof (parsed_recid));
- parsed_recid[sizeof (parsed_recid) - 1] = 0;
- return TRUE;
- } /* parse_infbuf() */
- /****************************************/
- /* */
- /* browser */
- /* */
- /****************************************/
- /* Program 1: displays records in input file,
- * or user selected records, and if confirmed,
- * writes their record ids to output file.
- */
- static int browser (void)
- {
- int done = FALSE;
- int pausing = FALSE;
- int redisplay_rec = FALSE;
- int pause_counter;
- time_t stamp;
- LLIST *llptr;
- char *ptr;
- char datestr[32]; /* "1946/04/17 13:03" */
- char userbuf[1024];
- char infbuf[1024];
- /* All writes to output file will have same date string in comment */
- time (&stamp);
- strftime (datestr, sizeof (datestr), "%Y/%m/%d %H:%M", localtime (&stamp));
- /* Main menu loop */
- while (!done) {
- if (DtSearchHasMessages ()) {
- putchar ('\n');
- PRINT_MESSAGES
- }
- /* Write main menu prompt */
- printf ( CATGETS(dtsearch_catd, MS_tomita, 10,
- "\n---------- SHOW NEXT RECORD ----------- Database = '%s'\n"
- "q QUIT. Current Record Count = %ld\n"
- "p Toggle PAUSE from %s.\n"
- "n NEXT INPUT file record.\n"
- "+ NEXT SEQUENTIAL database record.\n"
- "- PRIOR SEQUENTIAL database record.\n"
- "r REDISPLAY current record '%s'.\n"
- "x CONFIRM DELETION of current record.\n"
- "dxxx Change DATABASE to xxx.\n"
- "\"xxx GET record id xxx (embedded blanks are ok).\n"
- "> ") ,
- usrblk.dblk->name,
- usrblk.dblk->dbrec.or_reccount,
- (pausing) ? "on to OFF" : "off to ON",
- usrblk.objrec.or_objkey
- );
- /* Read user's response. Remove user's \n. */
- *userbuf = '\0';
- if ((fgets (userbuf, sizeof (userbuf), stdin)) == NULL) break;
- if (strlen(userbuf) && userbuf[strlen(userbuf)-1] == '\n')
- userbuf[strlen(userbuf)-1] = '\0';
- putchar ('\n');
- /* depending on response, get database address into usrblk */
- redisplay_rec = FALSE;
- switch (tolower (*userbuf)) {
- case 'q':
- done = TRUE;
- break;
- case 'd':
- change_database (userbuf + 1);
- continue;
- break;
- case 'p':
- pausing = !pausing;
- continue;
- break;
- case 'r':
- if (usrblk.objrec.or_objkey[0] == 0) {
- fprintf (aa_stderr,
- CATGETS(dtsearch_catd, MS_tomita, 11,
- "%s Record buffer empty.\n"),
- PROGNAME"267");
- continue;
- }
- redisplay_rec = FALSE;
- break;
- case '+':
- case '-':
- usrblk.request = (*userbuf == '+') ? OE_NEXT_DBA : OE_PREV_DBA;
- Opera_Engine ();
- break;
- case 'n':
- if (inf == NULL) {
- fprintf (aa_stderr,
- CATGETS(dtsearch_catd, MS_tomita, 12,
- "%s Input file unavailable.\n"),
- PROGNAME"282");
- continue;
- }
- *infbuf = '\0';
- if ((fgets (infbuf, sizeof (infbuf), inf)) == NULL)
- {
- fprintf (aa_stderr,
- CATGETS(dtsearch_catd, MS_tomita, 13,
- "%s No more records in input file.\n"),
- PROGNAME"288");
- fclose (inf);
- inf = NULL;
- continue;
- }
- if (strlen(infbuf) && infbuf[strlen(infbuf)-1] == '\n')
- infbuf[strlen(infbuf)-1] = '\0';
- if (!parse_infbuf (infbuf))
- continue;
- usrblk.request = OE_RECKEY2DBA;
- usrblk.query = parsed_recid;
- Opera_Engine ();
- break;
- case '\"':
- ptr = strtok (userbuf, "\"");
- if (ptr == NULL || *ptr == 0) {
- fprintf (aa_stderr,
- CATGETS(dtsearch_catd, MS_tomita, 14,
- "%s Invalid Record ID.\n"),
- PROGNAME"303");
- continue;
- }
- usrblk.request = OE_RECKEY2DBA;
- usrblk.query = ptr;
- Opera_Engine ();
- break;
- case 'x':
- /*
- * Write record id to output file. Format:
- * dbasename "recid" userid comments(date)...
- */
- fprintf (outf, DISCARD_FORMAT, usrblk.dblk->name,
- usrblk.objrec.or_objkey, usrblk.userid, datestr);
- printf ( CATGETS(dtsearch_catd, MS_tomita, 15,
- "%s '%s' appended to file of confirmed deletions.\n") ,
- PROGNAME"317", usrblk.objrec.or_objkey);
- continue;
- default:
- printf ("%s", CATGETS(dtsearch_catd, MS_tomita, 16, "...what?\n"));
- continue;
- } /* end switch */
- if (done)
- break;
- /* if user requested redisplay, skip the following OE code */
- if (redisplay_rec)
- goto DISPLAY_RECORD;
- /*
- * check return code from attempt to get opera database
- * address
- */
- if (usrblk.retncode == OE_WRAPPED)
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 17,
- "%s %s Engine wrapped to next record.\n") ,
- PROGNAME"333", OE_prodname);
- else if (usrblk.retncode != OE_OK)
- retncode_abort (334);
- /* retrieve the record and uncompress it */
- usrblk.request = OE_GETREC;
- Opera_Engine ();
- if (usrblk.retncode != OE_OK)
- retncode_abort (339);
- DISPLAY_RECORD:
- /* display the record's cleartext, character by character */
- printf ( CATGETS(dtsearch_catd, MS_tomita, 18,
- "\n\n"
- "Record: '%s'\n"
- "Abstract: '%s'\n"
- "--------------------------------------\n") ,
- usrblk.objrec.or_objkey,
- (usrblk.abstrbufsz > 0) ? usrblk.abstrbuf :
- CATGETS(dtsearch_catd, MS_misc, 1, "<null>"));
- pause_counter = 0;
- for (ptr = usrblk.cleartext; *ptr != 0; ptr++) {
- putchar (*ptr);
- /*
- * pause every so many lines so user can browse the
- * output
- */
- if (pausing && *ptr == '\n') {
- if (++pause_counter >= PAUSE_ROWS) {
- /* Msg 21 is used in two places */
- printf ( "%s", CATGETS(dtsearch_catd, MS_tomita, 21,
- "\n...push ENTER to continue... ") );
- *userbuf = '\0';
- if(NULL == fgets (userbuf, sizeof (userbuf), stdin)) {
- fprintf(stderr, "Failed to read from stdin\n");
- exit(EXIT_FAILURE);
- }
- if (strlen(userbuf) && userbuf[strlen(userbuf)-1] == '\n')
- userbuf[strlen(userbuf)-1] = '\0';
- putchar ('\n');
- pause_counter = 0;
- }
- }
- } /* end of cleartext printing */
- /* display the user notes if any, character by character */
- if (usrblk.notes != NULL) {
- printf ( CATGETS(dtsearch_catd, MS_tomita, 20,
- "--------------------------------------\n"
- "End of Text Blob for '%s':\n\n"
- "User Notes:\n"
- "--------------------------------------\n") ,
- usrblk.objrec.or_objkey);
- pause_counter += 5;
- for (llptr = usrblk.notes; llptr != NULL; llptr = llptr->link) {
- for (ptr = llptr->data; *ptr != '\0'; ptr++) {
- putchar (*ptr);
- if (pausing && *ptr == '\n')
- if (++pause_counter >= PAUSE_ROWS) {
- /* Msg 21 is used in two places */
- printf ( "%s", CATGETS(dtsearch_catd, MS_tomita, 21,
- "\n...push ENTER to continue... ") );
- *userbuf = '\0';
- if(NULL == fgets (userbuf, sizeof (userbuf), stdin)) {
- fprintf(stderr, "Failed to read from stdin 2\n");
- exit(EXIT_FAILURE);
- }
-
- if (strlen(userbuf) &&
- userbuf[strlen(userbuf)-1] == '\n')
- userbuf[strlen(userbuf)-1] = '\0';
- putchar ('\n');
- pause_counter = 0;
- }
- }
- }
- } /* end of user notes printing */
- printf ("--------------------------------------\n"
- "End of Record '%s'.\n", usrblk.objrec.or_objkey);
- } /* end of main menu loop */
- return 0;
- } /* browser() */
- /****************************************/
- /* */
- /* load_dbatab */
- /* */
- /****************************************/
- /* Subroutine of deleter(). Reads discard file containing
- * record ids to be deleted, converts to database addresses,
- * loads usrblk.dbatab up to max batch size.
- * Returns number of dba's added to table.
- * Returns 0 when file is empty after last batch.
- */
- static int load_dbatab (void)
- {
- static int read_next_rec = TRUE;
- static char last_dbname[24] = "";
- static DBLK *last_dblk;
- DB_ADDR *next_dba;
- char buf[1024];
- int first_err = TRUE;
- if (inf == NULL)
- return 0;
- usrblk.dbacount = 0;
- next_dba = usrblk.dbatab;
- KEEP_READING:
- /* MAIN LOOP - break it at EOF, max count, or dbname change */
- while (usrblk.dbacount < max_dbacount) {
- /*
- * Skip the read of the first record if the reason we left
- * main loop the last time was because of a database name
- * change, and the data from the last read is still in
- * parsed_dbname, _dblk, and _recid. Update usrblk.dblk
- * because it's based on the last table's database.
- */
- if (!read_next_rec) {
- read_next_rec = TRUE;
- usrblk.dblk = parsed_dblk;
- }
- else {
- *buf = '\0';
- if (fgets (buf, sizeof (buf), inf) == NULL)
- {
- fclose (inf);
- inf = NULL;
- break;
- }
- records_read++;
- buf[sizeof (buf) - 1] = 0; /* guarantee termination */
- if (strlen(buf) && buf[strlen(buf)-1] == '\n')
- buf[strlen(buf)-1] = '\0';
- /*
- * Parse line into dbname and recid. Skip line if
- * error.
- */
- if (!parse_infbuf (buf))
- continue;
- /* on very first read, save the database name */
- if (last_dbname[0] == 0) {
- strcpy (last_dbname, parsed_dbname);
- last_dblk = parsed_dblk;
- }
- } /* finished reading next rec in input file */
- /*
- * Test for change of database name. Restore usrblk.dblk
- * to reflect all the records on the dba table so far. Then
- * save the new dblk for when we are again called.
- */
- if (strcmp (last_dbname, parsed_dbname) != 0) {
- read_next_rec = FALSE;
- strcpy (last_dbname, parsed_dbname);
- usrblk.dblk = last_dblk;
- last_dblk = parsed_dblk;
- break;
- }
- /*
- * Call OE to get record's db address. Turn off debug
- * temporarily so won't flood output with messages.
- */
- usrblk.query = parsed_recid;
- usrblk.debug &= ~USRDBG_DELETE;
- usrblk.request = OE_RECKEY2DBA;
- Opera_Engine ();
- if (debug_mode) /* restore */
- usrblk.debug |= USRDBG_DELETE;
- if (DtSearchHasMessages ()) {
- putchar ('\n');
- PRINT_MESSAGES
- }
- if (usrblk.retncode == OE_WRAPPED) {
- if (first_err) {
- first_err = FALSE;
- fputc ('\n', aa_stderr);
- }
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 24,
- "%s Database %s, '%s' not found.\n") ,
- PROGNAME"482", parsed_dbname, parsed_recid);
- continue;
- }
- else if (usrblk.retncode != OE_OK)
- retncode_abort (486);
- /* add db address to growing table */
- *next_dba = usrblk.dba;
- next_dba++;
- usrblk.dbacount++;
- } /* end of main record read loop */
- /* It is possible to exit the main loop, because database changed
- * or whatever, but no records were added to usrblk.dbatab.
- * If there are still records to be read from the input file,
- * go back and try another pass.
- */
- if (inf != NULL && usrblk.dbacount == 0)
- goto KEEP_READING;
- return usrblk.dbacount;
- } /* load_dbatab() */
- /****************************************/
- /* */
- /* deleter */
- /* */
- /****************************************/
- /* Program 2: deletes records specified in input file.
- * Must be run offline when all online users have logged off.
- */
- static void deleter (char *infname)
- {
- int i;
- long records_deleted;
- time_t start_time, minutes, hours, seconds, elapsed;
- char buf[128];
- if (!yesarg) {
- printf ( CATGETS(dtsearch_catd, MS_tomita, 25,
- "\nDO NOT CONTINUE under any of the following circumstances:\n"
- "-> If the input file which lists record ids to be deleted is not\n"
- " named '%s'.\n"
- "-> If any users are still accessing the affected database(s).\n"
- "-> If any database files have not been backed up.\n\n"
- "If you are sure you are ready to start deleting, enter 'y' now... ") ,
- infname, OE_prodname);
- if(NULL == fgets (buf, sizeof(buf)-1, stdin)) {
- fprintf(stderr, "no input\n");
- return;
- }
- if (tolower (*buf) != 'y')
- return;
- }
- /* Make sure engine doesn't abort because of
- * recurring changes to d99 files.
- */
- OE_sitecnfg_mtime = 0L;
- /* Init table of db addrs */
- usrblk.dbatab = austext_malloc
- (sizeof (DB_ADDR) * (max_dbacount + 2), PROGNAME "531", NULL);
- usrblk.dbacount = 0; /* number of recs currently in table */
- /* Init status msg stuff */
- records_read = 0L;
- records_deleted = 0L;
- time (&start_time);
- signal (SIGINT, kill_delete);
- signal (SIGQUIT, kill_delete);
- signal (SIGTRAP, kill_delete);
- signal (SIGTERM, kill_delete);
- #ifdef SIGPWR
- signal (SIGPWR, kill_delete);
- #endif
- #ifdef _AIX
- signal (SIGXCPU, kill_delete); /* cpu time limit exceeded */
- signal (SIGDANGER, kill_delete); /* imminent paging space
- * crash */
- #endif
- /* MAIN LOOP */
- while (load_dbatab ()) {
- /*
- * Stop now if we have exceeded user specified time limit
- * or if user sent termination or interrupt signal.
- */
- if (shutdown_now)
- break;
- elapsed = time (NULL) - start_time;
- if (maxtime > 0L && elapsed >= maxtime)
- break;
- /* echo status for humans who might be watching */
- hours = elapsed / 3600L;
- seconds = elapsed - (3600L * hours); /* remaining after hours */
- minutes = seconds / 60L;
- seconds = seconds - (60L * minutes);
- printf ( CATGETS(dtsearch_catd, MS_tomita, 26,
- "%s %ld read, %ld deleted, %ldh %2ldm %2lds elapsed.\n"
- " Database '%s': Current record count = %ld, Batch size = %d.\n") ,
- aa_argv0, records_read, records_deleted,
- hours, minutes, seconds,
- usrblk.dblk->name, usrblk.dblk->dbrec.or_reccount, usrblk.dbacount);
- /*****fflush (stdout);*****/
- /* call OE to delete batch of records */
- usrblk.request = OE_DELETE_BATCH;
- Opera_Engine ();
- if (DtSearchHasMessages ()) {
- putchar ('\n');
- PRINT_MESSAGES
- }
- if (usrblk.retncode != OE_OK)
- retncode_abort (572);
- records_deleted += usrblk.dbacount;
- } /* end main loop */
- /* Print final status messages */
- elapsed = time (NULL) - start_time; /* total elapsed time */
- hours = elapsed / 3600L;
- seconds = elapsed - (3600L * hours); /* remaining after hours */
- minutes = seconds / 60L;
- seconds = seconds - (60L * minutes); /* remaining after hours
- * & mins */
- printf ( CATGETS(dtsearch_catd, MS_tomita, 27,
- "%s %ld records read from input file. %ld were deleted and\n"
- " %ld were not found in %ld hours, %ld minutes, %ld seconds,\n") ,
- aa_argv0, records_read, records_deleted,
- records_read - records_deleted,
- hours, minutes, seconds);
- /* Figure average time for a deletion */
- elapsed = (records_deleted) ? elapsed / records_deleted : 0L;
- minutes = elapsed / 60L;
- seconds = elapsed - (60L * minutes);
- printf ( CATGETS(dtsearch_catd, MS_tomita, 28,
- " or an average of %ld minutes, %ld seconds per record deleted.\n"),
- minutes, seconds);
- return;
- } /* deleter() */
- /****************************************/
- /* */
- /* main */
- /* */
- /****************************************/
- int main (int argc, char *argv[])
- {
- char *arg;
- time_t mytime;
- char timebuf[80];
- aa_argv0 = argv[0];
- setlocale (LC_ALL, "");
- dtsearch_catd = CATOPEN(FNAME_DTSRCAT, 0);
- time (&mytime);
- strftime (timebuf, sizeof (timebuf),
- CATGETS(dtsearch_catd, MS_misc, 22, "%A, %b %d %Y, %I:%M %p"),
- localtime (&mytime));
- printf (CATGETS(dtsearch_catd, MS_tomita, 29,
- "%s. Run %s.\n") ,
- aa_argv0, timebuf);
- austext_exit_last = print_exit_code;
- signal (SIGINT, DtSearchExit);
- signal (SIGTERM, DtSearchExit);
- /****memset (&usrblk, 0, sizeof(USRBLK));****/
- /* Validate program number argument */
- if (argc < 2) {
- BAD_ARGS:
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 30,
- "\nUSAGE: %s [options]\n"
- " -i Input file name. If not specified, defaults to %s.\n"
- " -d[v] Print debug statements.\n"
- " -dv turns on verbose (record-by-record) debugging.\n"
- " -t<N> Max desired number of seconds of run time.\n"
- " Ctrl-C/Break will also stop deletion at next record.\n"
- " -n<N> Change number of records in a batch from %d to <N>.\n"
- " -y Automatically answers 'yes' to Delete mode confirm prompt.\n"
- " -d trace deletion operations.\n") ,
- aa_argv0, FNAME_DISCARD_DATA,
- FNAME_CONFIRM_LIST, FNAME_CONFIRM_LIST, DBACOUNT);
- DtSearchExit (2);
- }
- prog = toupper (argv[1][0]);
- if (prog != 'B' && prog != 'D')
- goto BAD_ARGS;
- /* Initialize defaults depending on program mode */
- if (prog == 'B') {
- infname = FNAME_DISCARD_DATA;
- outfname = FNAME_CONFIRM_LIST;
- }
- else {
- infname = FNAME_CONFIRM_LIST;
- outfname = PROGNAME "654";
- }
- maxtime = 0L;
- /* Save rest of command line arguments */
- for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
- arg = *argv;
- switch (tolower (arg[1])) {
- case 'i':
- infname = arg + 2;
- break;
- case 'o':
- outfname = arg + 2;
- break;
- case 'd':
- debug_mode = TRUE;
- usrblk.debug |= USRDBG_DELETE;
- if (arg[2] == 'v')
- usrblk.debug |= USRDBG_VERBOSE;
- break;
- case 'y':
- yesarg = TRUE;
- break;
- case 't':
- maxtime = atol (arg + 2);
- break;
- case 'n':
- max_dbacount = atol (arg + 2);
- break;
- default:
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 31,
- "\n%s Unknown argument '%s'.\n") ,
- PROGNAME"689", arg);
- goto BAD_ARGS;
- } /* end switch */
- } /* end arg parsing */
- /* Open input file to test for its existence.
- * For the Browse program, file ptr 'inf' == NULL
- * means the file is not open.
- */
- if ((inf = fopen (infname, "r")) == NULL) {
- if (prog == 'D') {
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 32,
- "%s Unable to open input file '%s'.\n") ,
- PROGNAME"710", infname);
- goto BAD_ARGS;
- }
- }
- /* If browsing, get output file name and
- * open it to test for write permission.
- */
- if (prog == 'B') {
- if ((outf = fopen (outfname, "a ")) == NULL)
- /* the blank in "a " works around old aix bug */
- {
- fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_tomita, 33,
- "\n%s Unable to open output file '%s'.\n") ,
- PROGNAME"721", outfname);
- goto BAD_ARGS;
- }
- }
- /* Initialize the opera engine, i.e. open the database */
- printf ( CATGETS(dtsearch_catd, MS_tomita, 34,
- "Initializing %s engine...\n"),
- OE_prodname);
- strcpy (usrblk.userid, "ToMiTa");
- usrblk.request = OE_INITIALIZE;
- usrblk.query = AUSAPI_VERSION;
- Opera_Engine ();
- if (usrblk.retncode != OE_OK)
- retncode_abort (733);
- PRINT_MESSAGES
- if (prog == 'B')
- browser ();
- else
- deleter (infname);
- usrblk.request = OE_SHUTDOWN;
- Opera_Engine ();
- printf ( "%s", CATGETS(dtsearch_catd, MS_tomita, 36,
- "Normal engine shutdown.\n") );
- DtSearchExit (0);
- } /* main() */
- /******************* TOMITA.C *******************/
|