char *dir, *guess, *best;
{
/* set best, return distance 0..3 */
int d, nd, fd;
struct {
ino_t ino;
char name[DIRSIZ+1]; /* 1 more than in dir.h */
} nbuf;
nbuf.name[DIRSIZ] = '\0'; /* +1 for terminal '\0' */
if (dir[0] == '\0') /* current directory */
dir = ".";
d = 3; /* minimum distance */
if ((fd=open(dir, 0)) == -1)
return d;
while (read(fd, (char*)&nbuf, sizeof(struct direct)) > 0)
if (nbuf.ino) {
nd = spdist(nbuf.name, guess);
if (nd <= d && nd != 3) {
strcpy(best, nbuf.name);
d = nd;
if (d == 0) /* exact match */
break;
}
}
close(fd);
return d;
}
/* spdist: return distance between two names */
/*
* very rough spelling metric:
* 0 if the strings are identical
* 1 if two chars are transposed
* 2 if one char wrong, added or deleted
* 3 otherwise
*/
#define EQ(s,t) (strcmp(s,t) == 0)
spdist(s, t)
char *s, *t;
{
while (*s++ == *t)
if (*t++ == '\0')
return 0; /* exact match */
if (*--s) {
if (*t) {
if (s[1] && t[1] && *s == t[1] && *t == s[1] && EQ(s+2, t+2))
return 1; /* transposition */
if (EQ(s+1, t+1))
return 2; /* 1 char mismatch */
}
if (EQ(s+1, t))
return 2; /* extra character */
}
if (*t && EQ(s, t+1))
return 2; /* missing character */
return 3;
}
strindex(s, t) /* return index of t in s, -1 if none */
char *s, *t;
{
int i, n;
n = strlen(t);
for (i = 0; s[i] != '\0'; i++)
if (strncmp(s+i, t, n) == 0)
return i;
return -1;
}
/* sv: save new files */
#include
#include
#include
#include
char *progname;
main(argc, argv)
int argc;
char *argv[];
{
int i;
struct stat stbuf;
char *dir = argv[argc-1];
progname = argv[0];
if (argc <= 2)
error ("Usage: %s files... dir", progname);
if (stat(dir, festbuf) == -1)
error("can't access directory %s", dir);
if ((stbuf.st_mode & S_IFMT) != S_IFDIR)
error("%s is not a directory", dir);
for (i = 1; i < argc-1; i++)
sv(argv[i], dir);
exit(0);
}
sv(file, dir) /* save file in dir */
char *file, *dir;
{
struct stat sti, sto;
int fin, fout, n;
char target[BUFSIZ], buf[BUFSIZ], *index();
sprintf(target, "%s/%s", dir, file);
if (index(file, '/') != NULL) /* strchr() in some systems */
error("won't handle '/'s in %s", file);
if (stat(file, &sti) == -1)
error("can't stat %s", file);
if (stat(target, &sto) == -1) /* target not present */
sto.st_mtime = 0; /* so make it look old */
if (sti.st_mtime < sto.st_mtime) /* target is newer */
fprintf(stderr, "%s: %s not copied\n", progname, file);
else if ((fin = open(file, 0)) == -1)
error("can't open file %s", file);
else if ((fout = creat(target, sti.st_mode)) == -1)
error("can't create %s", target);
while ((n = read(fin, buf, sizeof buf)) > 0)
if (write(fout, buf, n) != n)
error("error writing %s", target);
close(fin);
close(fout);
}
#include "error.c"
#include
system(s) /* run command line s */
char *s;
{
int status, pid, w, tty;
int (*istat)(), (*qstat)();
...
if ((pid = fork()) == 0) {
...
execlp("sh", "sh", "-c", s, (char*)0);
exit(127);
}
...
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
while ((w = wait(&status)) != pid && w != -1)
;
if (w == -1)
status = -1;
signal(SIGINT, istat);
signal(SIGQUIT, qstat);
return status;
}
/*
* Safer version of system for interactive programs
*/
#include
#include
system(s) /* run command line s */
char *s;
{
int status, pid, w, tty;
int (*istat)(), (*qstat)();
extern char *progname;
fflush(stdout);
tty = open("/dev/tty", 2);
if (tty == -1) {
fprintf (stderr, "%s: can't open /dev/tty\n", progname);
return -1;
}
if ((pid = fork()) == 0) {
close(0);
dup(tty);
close(1);
dup(tty);
close(2);
dup(tty);
close(tty);
execlp("sh", "sh", "-c", s, (char*)0);
exit(127);
}
close(tty);
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
while ((w = wait(&status)) != pid && w != -1)
;
if (w == -1)
status = -1;
signal(SIGINT, istat);
signal(SIGQUIT, qstat);
return status;
}
/* timeout: set time limit on a process */
#include
#include
int pid; /* child process id */
char *progname;
main(argc, argv)
int argc;
char *argv[];
{
int sec = 10, status, onalarm();
progname = argv[0];
if (argc > 1 && argv[1][0] == '-') {
sec = atoi(&argv[1][1]);
argc--;
Читать дальше
Конец ознакомительного отрывка
Купить книгу