summaryrefslogtreecommitdiffstats
path: root/lib/libmytinfo/findterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libmytinfo/findterm.c')
-rw-r--r--lib/libmytinfo/findterm.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/lib/libmytinfo/findterm.c b/lib/libmytinfo/findterm.c
new file mode 100644
index 0000000..1fe5a9b
--- /dev/null
+++ b/lib/libmytinfo/findterm.c
@@ -0,0 +1,286 @@
+/* findterm.c
+ *
+ * By Ross Ridge
+ * Public Domain
+ * 92/02/01 07:29:56
+ *
+ */
+
+#include "defs.h"
+
+#include <ctype.h>
+#include <fcntl.h>
+#ifdef USE_STDDEF
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#ifdef __FreeBSD__
+#include <unistd.h>
+#endif
+
+#ifdef USE_SCCS_IDS
+static const char SCCSid[] = "@(#) mytinfo findterm.c 3.2 92/02/01 public domain, By Ross Ridge";
+#endif
+static int linecnt;
+
+static int
+getln(f, buf, len)
+FILE *f;
+register char *buf;
+int len; {
+ register int c, i = 0;
+
+ while((c = getc(f)) == '#') {
+ linecnt++;
+ while((c = getc(f)) != '\n')
+ if (c == EOF)
+ return -1;
+ }
+
+ while(c != '\n') {
+ if (c == EOF)
+ return -1;
+ if (i < len) {
+ i++;
+ *buf++ = c;
+ }
+ c = getc(f);
+ }
+
+ while(isspace(*(buf-1))) {
+ buf--;
+ i--;
+ }
+
+ *buf = '\0';
+ return i;
+}
+
+static int
+_findterm2(name, file, buf)
+char *name, *buf;
+char *file; {
+ char line[MAX_LINE];
+ FILE *f;
+ register char *sp, *dp;
+ int c;
+ int l;
+ int cont;
+ int fd;
+ struct stat st;
+
+ linecnt = 0;
+
+#ifdef DEBUG
+ printf("open: %s\n", file);
+#endif
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ return -1;
+ if (fstat(fd, &st) == -1) {
+ close(fd);
+ return -1;
+ }
+ if ((st.st_mode & 0170000) == 0040000) {
+ sprintf(buf, "%s/%c/%s", file, name[0], name);
+ close(fd);
+ fd = open(buf, O_RDONLY);
+ if (fd == -1)
+ return -1;
+ if (read(fd, buf, MAX_BUF) < 12
+ || buf[0] != 032 || buf[1] != 1) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ return 3;
+ }
+ f = fdopen(fd, "r");
+ if (f == NULL) {
+ close(fd);
+ return -1;
+ }
+
+ while ((l = getln(f, buf, MAX_LINE)) != -1) {
+ linecnt++;
+ if (!isspace(buf[0]) && l != 0) {
+ sp = buf + l - 1;
+ cont = 0;
+ switch(*sp) {
+ case '\\':
+ cont = 1;
+ *sp = '\0';
+ /* FALLTHROUGH */
+ case ':':
+ sp = buf;
+ dp = line;
+ while (*sp != ':') {
+ if (*sp == '\0' && cont &&
+ (l = getln(f, buf, MAX_LINE))
+ != -1) {
+ linecnt++;
+ sp = buf;
+ if (l > 0 && buf[l-1] == '\\')
+ cont = 1;
+ else
+ cont = 0;
+ continue;
+ }
+ if (*sp == '\0') {
+#ifdef DEBUG
+ printf("bad line (%d)\n",
+ linecnt);
+ fclose(f);
+ return -2;
+#else
+ goto err;
+#endif
+ }
+ *dp++ = *sp++;
+ }
+ *dp = '\0';
+ if (!_tmatch(line, name))
+ break;
+ if (!cont) {
+ fclose(f);
+ return 1;
+ }
+ l = strlen(buf);
+ dp = buf + l;
+ while((c = getc(f)) != EOF && l < MAX_BUF) {
+ if (c == '\n')
+ break;
+ if (c == '\\') {
+ c = getc(f);
+ if (c == EOF)
+ break;
+ if (c == '\n') {
+ c = getc(f);
+ if (c == EOF)
+ break;
+ if (c == '#') {
+ while((c = getc(f)) != EOF && c != '\n');
+ if (c == EOF)
+ break;
+ continue;
+ }
+ *dp++ = c;
+ continue;
+ }
+ *dp++ = '\\';
+ *dp++ = c;
+ continue;
+ }
+ *dp++ = c;
+ }
+ *dp = '\0';
+ fclose(f);
+ return 1;
+ case ',':
+ sp = buf;
+ dp = line;
+ while(*sp != ',')
+ *dp++ = *sp++;
+ *dp = '\0';
+ if (!_tmatch(line, name))
+ break;
+ dp = buf + l;
+ while ((c = getc(f)) != EOF && l < MAX_BUF) {
+ if (c == '\n') {
+ c = getc(f);
+ if (isspace(c))
+ continue;
+ if (c == '\n') {
+ ungetc(c, f);
+ continue;
+ }
+ if (c == '#') {
+ while((c = getc(f)) != EOF)
+ if (c == '\n')
+ break;
+ if (c == EOF)
+ break;
+ ungetc(c, f);
+ continue;
+ }
+ break;
+ }
+ *dp++ = c;
+ l++;
+ }
+ *dp = '\0';
+ fclose(f);
+ return 2;
+ default:
+ err:
+#ifdef DEBUG
+ printf("strange line (%d)\n", linecnt);
+#endif
+ break;
+ }
+ }
+ }
+ fclose(f);
+ return 0;
+}
+
+int
+_findterm(name, path, buf)
+char *name;
+struct term_path *path;
+char *buf; {
+ register char *s, *d;
+ int r = 0;
+ while(path->file != NULL) {
+ switch(path->type) {
+ case 0:
+ r = _findterm2(name, path->file, buf);
+ break;
+ case 1:
+ if (path->file[0] == '/') {
+ r = _findterm2(name, path->file, buf);
+ } else {
+ s = path->file;
+ d = buf;
+ while(*s != '\0' && *s != ':')
+ *d++ = *s++;
+ *d = '\0';
+ if (_tmatch(buf, name)) {
+ while(*s != '\0')
+ *d++ = *s++;
+ return 1;
+ }
+ r = 0;
+ }
+ break;
+ case 2:
+ if (path->file[0] == '/') {
+ r = _findterm2(name, path->file, buf);
+ } else {
+ s = path->file;
+ d = buf;
+ while(*s != '\0' && *s != ',')
+ *d++ = *s++;
+ *d = '\0';
+ if (_tmatch(buf, name)) {
+ while(*s != '\0')
+ *d++ = *s++;
+ return 2;
+ }
+ r = 0;
+ }
+ break;
+ default:
+ r = 0;
+ break;
+ }
+ if (r == 1 || r == 2 || r == 3) {
+#ifdef DEBUG
+ printf("found in %s\n", path->file);
+#endif
+ break;
+ }
+ path++;
+ }
+ return r;
+}
OpenPOWER on IntegriCloud