mirror of
https://github.com/freebsd/freebsd-src
synced 2024-11-05 18:22:52 +00:00
286 lines
4.6 KiB
C
286 lines
4.6 KiB
C
/* 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;
|
|
}
|