Example #1
0
/* Returns pointer to dbnames array.
 * Used after database or config file changes to trigger
 * engine reinitialization and to reaccess the database names.
 */
int	DtSearchReinit (char ***dbnames, int *dbcount)
{
    aa_check_initialization();
    usrblk.request = OE_PING;
    Opera_Engine();
    switch (usrblk.retncode) {
	case OE_REINIT:
	    if (save_init_switches & DtSrInANY_DEBUG) {
		fputs (PROGNAME"755 "
		    "DtSearchReinit: Engine did return REINIT.\n",
		    aa_stderr);
		fflush (aa_stderr);
	    }
	    aa_reinit();
	    /*  fall thru to OK... */

	case OE_OK:
	    *dbnames = ausapi_dbnamesv;
	    *dbcount = ausapi_dbnamesc;
	    return DtSrOK;

	default:
	    return DtSrERROR;
    }
}  /* DtSearchReinit() */
Example #2
0
/* Mallocs and returns cleartext of a record given database address (dba).
 * fzkey integers start at bkt #2, just like categories.
 * WARNING! USER SHOULD NEITHER MALLOC NOR FREE HIS CLEARTEXT POINTER!
 */
int             DtSearchRetrieve (
                    char *dbname,	/* 1 - 8 char database name */
                    DB_ADDR dba,	/* database address from dittolist */
                    char **cleartext,	/* cleartext put here (freed first) */
                    long *clearlen,	/* length of returned cleartext */
                    int *fzkeyi)	/* ptr to array of FZKEYSZ integers */
{
    if (!valid_dbname (dbname))
	return DtSrREINIT;
    usrblk.dba = dba;
    usrblk.request = OE_GETREC;
    Opera_Engine ();

    /* Set this func's retn value based on engine's retncode, and return. */
    switch (usrblk.retncode) {
	case OE_OK:
	    /*
	     * WARNING! USER SHOULD NEITHER MALLOC NOR FREE HIS
	     * CLEARTEXT POINTER. 
	     */
	    *cleartext = usrblk.cleartext;	/* user MUST leave
						 * cleartext alone */
	    *clearlen = usrblk.clearlen;
	    return DtSrOK;

	case OE_NOTAVAIL:
	    return DtSrNOTAVAIL;

	case OE_ABORT:
	    return DtSrABORT;

	case OE_REINIT:
	    return aa_reinit ();

	case OE_NOOP:
	    return DtSrFAIL;

	default:
	    /*
	     * Includes all unexpected return codes. Probable
	     * program error.  Msgs may or may not say why. 
	     */
	    return DtSrERROR;
    }	/* end switch */
}  /* DtSearchRetrieve() */
Example #3
0
/* Mallocs and returns hitwords array for passed text string
 * using database and stems array from last search.
 * The stems ptr may be NULL, but if specified
 * the passed stems array MUST be defined:
 *      char   stems [DtSrMAX_STEMCOUNT] [DtSrMAXWIDTH_HWORD].
 */
int             DtSearchHighlight (
                    char *dbname,	/* database name */
                    char *cleartext,	/* text to be hilited */
                    DtSrHitword ** hitwords,
					/* where to put hitwords array */
                    long *hitwcount,	/* num items in hitwords array */
                    int search_type,	/* [opt] override save_search_type */
                    char *stems,	/* [opt] override last search stems */
                    int stemcount	/* num stems in stems array */
)
{
    int             i;
    char           *cptr;

    if (!valid_dbname (dbname))
	return DtSrREINIT;

    /* copy cleartext to usrblk if necessary */
    if (cleartext == NULL || cleartext[0] == 0) {
	sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 40,
		"%1$s Null cleartext.  No highlighting performed."),
	    PROGNAME "349 ", dbname);
	DtSearchAddMessage (sprintbuf);
	return DtSrERROR;
    }
    if (cleartext != usrblk.cleartext) {
	if (usrblk.cleartext != NULL)
	    free (usrblk.cleartext);
	usrblk.clearlen = strlen (cleartext);
	usrblk.cleartext = austext_malloc (usrblk.clearlen + 16,
	    PROGNAME "267", NULL);
	strcpy (usrblk.cleartext, cleartext);
    }

    if (search_type)
	usrblk.search_type = search_type;
    else
	usrblk.search_type = save_search_type;

    if (stems) {
	if (stemcount > DtSrMAX_STEMCOUNT) {
	    sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 1072,
		"%s Program Error: Stem count (%d) greater than maximum (%d)."),
		PROGNAME"1072", stemcount, DtSrMAX_STEMCOUNT);
	    DtSearchAddMessage (sprintbuf);
	    return DtSrERROR;
	}
	usrblk.stemcount = stemcount;
	cptr = stems;
	for (i = 0; i < stemcount; i++) {
	    strcpy (usrblk.stems[i], cptr);
	    cptr += DtSrMAXWIDTH_HWORD;
	}
    }

    usrblk.request = OE_HILITE_STEMS;
    Opera_Engine ();

    /* Set this func's retn value based on engine's retncode, and return. */
    switch (usrblk.retncode) {
	case OE_OK:
	    /*
	     * Note that the following assignment works even if the
	     * user's hitwords arg is in fact &usrblk.hitwords and
	     * hitwcount is in fact &usrblk.hitwcount. 
	     */
	    *hitwords = usrblk.hitwords;
	    *hitwcount = usrblk.hitwcount;
	    return DtSrOK;

	case OE_ABORT:
	    return DtSrABORT;

	case OE_REINIT:
	    return aa_reinit ();

	case OE_NOOP:
	case OE_NOTAVAIL:
	    return DtSrFAIL;

	default:
	    /*
	     * Includes OE_BAD_QUERY and all unexpected return
	     * codes. Probable program error.  Msgs may or may not
	     * say why. In case they don't, put OE's retncode on
	     * msglist. 
	     */
	    if (!ausapi_msglist) {
		sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 1342,
		    "%s Search Engine Error %d for highlight request for "
		    "database '%s', hit word count=%ld, search type='%c', text='%.30s'"),
		    PROGNAME "1342",
		    usrblk.retncode, dbname, *hitwcount, search_type,
		    NULLORSTR (cleartext));
		DtSearchAddMessage (sprintbuf);
	    }
	    return DtSrERROR;
    }	/* end switch */
}  /* DtSearchHighlight() */
Example #4
0
/* Returns hitlist (dittolist) if search successful.
 * If dbname is NULL, assumes name from first dblk on dblist.
 * Will work correctly even if arg dittolist == &usrblk.dittolist.
 * Only return hits 'after' date1 and 'before' date2.
 * NULL in one date field means search not limited in that direction.
 * NULL in both date fields means search not restricted by dates.
 * NULL is also permitted in stems, but if stems is
 * not NULL, the passed stems array MUST be defined:
 *      char   stems [DtSrMAX_STEMCOUNT] [DtSrMAXWIDTH_HWORD].
 * If query is fzkeyi, it must point to
 * array of FZKEYSZ integers.
 * DtSearchQuery() was formerly named ausapi_search().
 */
int             DtSearchQuery (
		void	*qry,		/* query, fzkeyi, nav string */
		char	*dbname,	/* database name from dbnamesv */
		int	search_type,	/* 'P', 'W', 'S', 'T', 'Z', or 'N' */
		char	*date1,		/* "yyyy mm dd", 3 numeric tokens */
		char	*date2,		/* date1 earlier than date2 */
		DtSrResult
			**dittolist,	/* put hitlist here */
		long	*dittocount,	/* put num items on returned hitlist */
		char	*stems,		/* put stems array here */
		int	*stemcount)	/* put size of stems array */
{
    int             final_request;
    int             i;
    char           *ptr;
    DBLK           *db;
    LLIST          *llp;
    enum { TEXT, NAVSTRING, FZKEYI }
                    qryarg;
    char            date1str[24];

    if (!valid_dbname (dbname))
	return DtSrREINIT;

    /* Verify valid search_type and set flag
     * to tell us how to interpret 'qry' arg.
     */
    switch (search_type) {
	case 'P':	/* statistical search */
	    qryarg = TEXT;
	    final_request = OE_SRCH_STATISTICAL;
	    break;

	case 'W':	/* exact words search */
	    qryarg = TEXT;
	    final_request = OE_SRCH_WORDS;
	    break;

	case 'S':	/* exact stems search */
	    qryarg = TEXT;
	    final_request = OE_SRCH_STEMS;
	    break;

	default:
	    sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 20,
		    "%1$s Invalid search_type '%2$c'."),
		PROGNAME "172 ", search_type);
	    DtSearchAddMessage (sprintbuf);
	    return DtSrERROR;

    }	/* end switch on search_type */

    /* Validate the 'qry' argument */
    if (qry == NULL) {
QUERY_ERROR:
	sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 30,
		"%s Null query.  No search performed."),
	    PROGNAME"81");
	DtSearchAddMessage (sprintbuf);
	return DtSrFAIL;
    }

    /* If qry is a char string, it must be nonempty. */
    if (qryarg != FZKEYI && ((char *) qry)[0] == 0)
	goto QUERY_ERROR;

    /* If qry is text to be sent as is to engine,
     * copy it over now to userblk.
     */
    if (qryarg == TEXT && qry != usrblk.query) {
	if (usrblk.query != NULL)
	    free (usrblk.query);
	usrblk.query = austext_malloc (strlen (qry) + 16, PROGNAME "102", NULL);
	strcpy (usrblk.query, qry);
    }

    /* Validate the 'date' args and place them into usrblk. */
    if (!both_valid_dates (date1, date2))
	return DtSrFAIL;

    /* Finish setup usrblk for final search */
    usrblk.flags |= USR_NO_ITERATE;	/* must ALWAYS be ON in this api */
    usrblk.request = final_request;
    db = usrblk.dblk;
    db->maxhits = aa_maxhits;
    if (qryarg == TEXT)
	save_search_type = usrblk.search_type = search_type;

    if (usrblk.debug & USRDBG_SRCHCMPL) {
	ptr = sprintbuf;
	for (i = 0; i < db->ktcount; i++) {
	    if (db->keytypes[i].is_selected)
		*ptr++ = '*';
	    *ptr++ = db->keytypes[i].ktchar;
	    *ptr++ = ' ';
	}
	*(--ptr) = 0;
	strcpy (date1str, objdate2fzkstr (usrblk.objdate1));
	fprintf (aa_stderr,
	    PROGNAME "353 DtSearchQuery(): dbname='%s' srchtype='%c'\n"
	    "  maxhits=%d keytypes='%s'\n"
	    "  date1='%s' -> %s.  date2='%s' -> %s.\n"
	    "  query='%.60s'\n",
	    db->name, search_type, db->maxhits, sprintbuf,
	    NULLORSTR (date1), date1str,
	    NULLORSTR (date2), objdate2fzkstr (usrblk.objdate2),
	    NULLORSTR (usrblk.query));
	fflush (aa_stderr);
    }

    /* Final engine call, the search itself... */
    Opera_Engine ();

END_OF_SEARCH:
    if (usrblk.debug & USRDBG_SRCHCMPL) {
	/* count msgs */
	i = 0;
	for (llp = ausapi_msglist; llp != NULL; llp = llp->link)
	    i++;
	fprintf (aa_stderr, PROGNAME "380 Return from Search:  "
	    "retncode=%d  hitcount=%ld  srchmsgs=%d.\n",
	    usrblk.retncode, usrblk.dittocount, i);
	fflush (aa_stderr);
    }

    /* Set this func's retn value based on engine's retncode, and return. */
    switch (usrblk.retncode) {
	case OE_OK:
	    /*
	     * Transfer usrblk.dittolist to user's own dittolist
	     * pointer. Also he MUST use DtSearchFreeResults()
	     * between calls. Otherwise the code below will cause a
	     * memory leak. 
	     */
	    *dittolist = usrblk.dittolist;
	    *dittocount = usrblk.dittocount;
	    usrblk.dittolist = NULL;
	    usrblk.dittocount = 0;
	    if (stems) {
		*stemcount = usrblk.stemcount;
		for (i = 0; i < *stemcount; i++) {
		    strcpy (stems, usrblk.stems[i]);
		    stems += DtSrMAXWIDTH_HWORD;
		}
	    }
	    return DtSrOK;

	case OE_NOTAVAIL:
	    return DtSrNOTAVAIL;

	case OE_ABORT:
	    return DtSrABORT;

	case OE_REINIT:
	    return aa_reinit ();

	case OE_BAD_QUERY:
	    /* Query was invalid.  Tell the user why. */
	    if (ausapi_msglist == NULL) {
		sprintf (sprintbuf,
		    catgets (dtsearch_catd, MS_ausapi, 806,
			"%s Query insufficient or search options "
			"incompatible with database '%s' to commence search."),
		    PROGNAME "806", usrblk.dblk->name);
		DtSearchAddMessage (sprintbuf);
	    }
	    return DtSrFAIL;

	case OE_NOOP:
	    /* Search was unsuccessful. Msgs should say why. */
	    return DtSrFAIL;

	default:
	    /*
	     * Includes OE_SEARCHING, OE_USER_STOP, etc. Probable
	     * program error.  Msgs may or may not say why. 
	     */
	    return DtSrERROR;
    }	/* end switch */
}  /* DtSearchQuery() */
Example #5
0
/* Initializes ausapi and the AusText engine (performs OE_INIT).
 * Must be first ausapi call.  Must be called only once (reinit?).
 * See dtsearch.doc for specs.
 */
int             DtSearchInit (
                    char	*argv0,
                    char	*userid,
                    long	switches,
                    char	*config_file,
                    FILE	*err_file,
                    char	***dbnames,
                    int		*dbcount)
{
    if (aa_is_initialized) {
	sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 621,
	    "%1$s %2%s has already been initialized."),
	    PROGNAME"621", PRODNAME);
	DtSearchAddMessage (sprintbuf);
	return DtSrFAIL;
    }

    aa_is_initialized = TRUE;
    save_init_switches = switches;
    if (argv0)
	aa_argv0 = argv0;
    if (err_file)
	aa_stderr = err_file;
    else
	aa_stderr = stderr;

    sprintbuf = austext_malloc (SPRINTBUFSZ, PROGNAME "135", NULL);

    /* Open msgs and help text catalogs. */
    if (switches & (DtSrInNOLOCALE == 0)) {
	setlocale (LC_ALL, "");
	dtsearch_catd = catopen (FNAME_DTSRCAT, 0);
    }

    /* Register AusText abort signal handlers.
     * This ensures that if caller is killed,
     * engine will shutdown gracefully.
     */
    if (switches & DtSrInSIGNAL) {
	if (!(switches & DtSrInENAB_NOHUP))
	    signal (SIGHUP, signal_abort);	/* trap hangups */
	signal (SIGINT, signal_abort);	/* interrupt, ctrl-c */
	signal (SIGQUIT, signal_abort);	/* quit, ctrl-d */
	signal (SIGKILL, signal_abort);	/* (kill -9, cannot be trapped) */
	signal (SIGTERM, signal_abort);	/* kill [-15], sfwr terminate */
#ifdef SIGPWR
	signal (SIGPWR, signal_abort);	/* power failure imminent */
#endif
#ifdef _AIX
	signal (SIGXCPU, signal_abort);	/* cpu time limit exceeded */
	signal (SIGDANGER, signal_abort);  /* imminent paging space crash */
#endif
    }

    /* If user name was not passed, get it from LOGNAME environment var */
    if (userid == NULL || *userid == 0)
	if ((userid = (char *) getenv ("LOGNAME")) == NULL) {
	    sprintf (sprintbuf, catgets (dtsearch_catd, MS_ausapi, 187,
		"%1$s Missing both userid and LOGNAME environment variable."),
		PROGNAME "187 ");
	    DtSearchAddMessage (sprintbuf);
	    return DtSrFAIL;
	}

    /* initialize usrblk fields */
    memset (&usrblk, 0, sizeof (USRBLK));
    strncpy (usrblk.userid, userid, 8);
    usrblk.userid[8] = 0;
    usrblk.flags |= USR_NO_INFOMSGS;	/* standard for ausapi */
    usrblk.flags |= USR_SORT_WHITL;	/* standard for ausapi */
    usrblk.flags |= USR_NO_ITERATE;	/* must ALWAYS be on in
					 * this api */

    if (switches & DtSrInIDEBUG)
	usrblk.debug |= USRDBG_RARE;
    if (switches & DtSrInSDEBUG)
	usrblk.debug |= USRDBG_SRCHCMPL;
    if (switches & DtSrInRDEBUG)
	usrblk.debug |= USRDBG_RETRVL;
    /* Secret unadvertised feature.  High order 2 bytes
     * are direct settings of lower 2 bytes of usrblk.debug.
     */
    usrblk.debug |= switches >> 16;

    /* Set vista's db_oflag from DtSrInRDWR switch.
     * Note the vista flag and the switch are inverses
     * of each other (RDWR vs. RDONLY).
     */
    if ((switches & DtSrInRDWR) == 0)
	db_oflag = O_RDONLY;

    /* Prespecify site config file to engine */
    if (config_file)
	OE_sitecnfg_fname = (char *) strdup (config_file);

    /* initialize AusText Engine */
    usrblk.request = OE_INITIALIZE;
    usrblk.query = AUSAPI_VERSION;
    Opera_Engine ();
    usrblk.query = NULL;  /* so we don't try to free it at query time */
    if (usrblk.retncode != OE_OK)
	return DtSrFAIL;

    build_dbnames_array ();
    if (dbnames) {
	*dbnames = ausapi_dbnamesv;
	if (!dbcount) {
	    sprintf (sprintbuf, catgets(dtsearch_catd, MS_ausapi, 7,
		"%s dbnames specified but not dbcount."),
		PROGNAME"304");
	    DtSearchAddMessage (sprintbuf);
	    return DtSrFAIL;
	}
	*dbcount = ausapi_dbnamesc;
    }

    return DtSrOK;
}  /* DtSearchInit() */
Example #6
0
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() */
Example #7
0
/* 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);

	fgets (buf, sizeof(buf)-1, stdin);
	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() */
Example #8
0
/* 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() */
Example #9
0
/* 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';
		    fgets (userbuf, sizeof (userbuf), stdin);
    		    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';
		            fgets (userbuf, sizeof (userbuf), stdin);
    		            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() */