/* fastopen.c -- Copyright 1996 Liam R. E. Quin. * All Rights Reserved. * This code is NOT in the public domain. * See the file COPYRIGHT for full details. */ /* fastopen -- * read filenames and byte offsets on stdin, and * open the files, and read up to the byte offsets. * * input is * open _n_ _filename_ * seek _n_ _position_ * close _n_ * requests may be interleaved, up to a max of 100. * * The program is intended to be run in the backgrund by lqaddfile, and hence * does not gnerally produce diagnostics unless called with the -d option. * * Format errors, attempts to close a file not opened, or to re-use an _n_ * without closing it first are all fatal errors that are reported. * * $Id: fastopen.c,v 1.1 1996/08/14 17:02:12 lee Exp $ */ static char *Version = "@(#) $Id: fastopen.c,v 1.1 1996/08/14 17:02:12 lee Exp $"; #include "globals.h" /* defines and declarations for database filenames */ #include "error.h" #include #include #include #include #include #ifdef HAVE_STRING_H # include #else # include #endif #ifdef HAVE_STDLIB_H # include #endif #include #ifdef HAVE_FCNTL_H # include #endif #include "fileinfo.h" #include "wordinfo.h" #include "wordrules.h" #include "emalloc.h" #include "addfile.h" #include "lqutil.h" #include "liblqtext.h" #include "filter.h" #include "lqtrace.h" #include "revision.h" typedef struct { int n; /* -1 if not opened */ int fd; long pos; } t_oneFile; #define MAXFILES 100 t_oneFile Files[MAXFILES]; int nFiles = 0; static int FindMe(n) int n; { register int i; for (i = 0; i < nFiles; i++) { if (Files[i].n == n) { return i; } } return -1; } int main(argc, argv) int argc; char *argv[]; { char linebuffer[2000]; int OK; t_LQTEXT_Database *db; t_lqdbOptions *Options; Options = LQT_InitFromArgv(argc, argv); db = LQT_OpenDatabase(Options, O_RDONLY, 0); if (!db) { Error(E_FATAL, "failed to open database."); } { int i; for (i = 0; i < nFiles; i++) { Files[i].n = Files[i].fd = -1; } } while (fgets(linebuffer, sizeof(linebuffer), stdin) != (char *) NULL) { char *p; LQT_Trace(LQTRACE_DEBUG, "Line: %s", linebuffer); for (p = linebuffer; *p; p++) { if (*p == '\n') { *p = '\0'; break; } } OK = 0; /* default = bad */ switch (linebuffer[0]) { case 'o': if (strncmp(linebuffer, "open ", 5) == 0) { OK = 1; if (nFiles == MAXFILES) { fprintf(stderr, "%s: %d files already open\n", progname, nFiles); exit(1); } else { int n; n = 0; for (p = &linebuffer[5]; *p; p++) { if (!isdigit(*p)) { break; } n *= 10; n += *p - '0'; } if (*p != ' ' || !*++p) { OK = 0; fprintf(stderr, "%s: missing filename?\n", progname); break; } if (FindMe(n) != -1) { fprintf(stderr, "%s: %d already open!\n", progname, n ); exit(1); } /* p points to the start of the filename */ p = LQT_FindFile(db, p); if (!p) { if (LQT_TraceFlagsSet(LQTRACE_VERBOSE|LQTRACE_DEBUG)) { Error(E_WARN|E_SYS, "FindFile returned null..."); } OK = 0; break; } Files[nFiles].fd = open(p, O_RDONLY, 0644); if (Files[nFiles].fd < 0) { if (LQT_TraceFlagsSet(LQTRACE_VERBOSE|LQTRACE_DEBUG)) { perror(p); fprintf(stderr, "%s: failed to open %s\n", progname, p ); } OK = 0; break; } Files[nFiles].n = n; Files[nFiles].pos = 0L; /* read a single byte */ (void) read(Files[nFiles].fd, linebuffer, 1); LQT_Trace(LQTRACE_DEBUG, "%s: OPEN %d -> %d, %s", progname, n, Files[nFiles].fd, p ); nFiles++; } /* else */ } break; case 's': if (strncmp(linebuffer, "seek ", 5) == 0) { fprintf(stderr, "%s: unimplemented: %s\n", progname, linebuffer ); OK = 1; } break; case 'c': OK = 0; if (strncmp(linebuffer, "close ", 6) == 0) { int n; n = 0; for (p = &linebuffer[6]; *p; p++) { if (!isdigit(*p)) { break; } n *= 10; n += *p - '0'; } if (*p) { fprintf(stderr, "%s: close: usage: close number \\n\n", progname ); break; } else { int Me; Me = FindMe(n); if (Me < 0) { fprintf(stderr, "%s: %d not open\n", progname, n); break; } else { int j; LQT_Trace(LQTRACE_DEBUG, "%s: CLOSE %d\n", progname, n ); (void) close(Files[Me].fd); /* move down */ for (j = Me + 1; j < nFiles; j++, Me++) { Files[Me] = Files[j]; } nFiles--; OK = 1; break; } } } break; default: fprintf(stderr, "%s: unrecognised command...\n", progname); OK = 0; } if (!OK) { fprintf(stderr, "%s: bad input: %s", progname, linebuffer); } } return 0; }