ref: 93c347adf541f8588aa610f66040dd96d39ccc3e
dir: /fingerd.c/
#include <u.h> #include <libc.h> #include <auth.h> #include <bio.h> #define BUFSIZ 8192 char *LOG = "fingerd"; char *nsfile = "/lib/namespace.finger"; char *usernotfound = "/lib/finger/usernotfound"; char *filenotfound = "/lib/finger/filenotfound"; char *motd = "/lib/finger/motd"; int puserlist = 1; int vaccess(char *file) { int fd; fd = open(file, OREAD); if (fd < 0){ return 0; } close(fd); return 1; } void strrepl(char *str, char f, char t) { while (*str != 0){ if (*str == f) *str = t; str++; } } int cat(char *file, int perr) { int n, fd; char buf[BUFSIZ]; fd = open(file, OREAD); if (fd < 0){ if (perr) print("File %s not Found.\r\n", file); return 0; } while ((n = read(fd, buf, BUFSIZ)) > 0) if (write(1, buf, n) != n) print("Error writing data!\r\n"); close(fd); return 1; } char* splitpath(char *req) { char *file; file = strchr(req, '+'); if (file == nil || strlen(file) <= 1) return "finger"; file[0] = 0; strrepl(file+1, '+', '/'); return file+1; } void printuserinfo(char *user) { print("%s\r\n", user); } void printuserlist(void) { Dir *dirbuf; char *path; int fd, n, i; fd = open("/usr", OREAD); if (fd < 0){ print("Can't list users.\r\n"); return; } n = dirreadall(fd, &dirbuf); close(fd); if (n) print("User list:\r\n"); else print("No users.\r\n"); for (i = 0; i < n; i++){ path = smprint("/usr/%s/finger/finger", dirbuf[i].name); if (vaccess(path)){ free(path); printuserinfo(dirbuf[i].name); } } } void printnouser(char *user) { if (!cat(usernotfound, 0)) print("User '%s' not found or private.\r\n", user); } void printnofile(char *file) { if (!cat(filenotfound, 0)) print("File '%s' not found.\r\n", file); syslog(1, LOG, "file %s not found", file); } void printglobalfile(char *file) { if (bind("/lib/finger/tree/", "/", MREPL) < 0) { print("unable to bind.\r\n"); syslog(1, LOG, "unable to bind /lib/finger/tree: %r"); return; } chdir("/"); if (!vaccess(file)){ printnofile(file); return; } if (!cat(file, OREAD)) printnofile(file); } void printuserfile(char *user, char *file) { char *path; path = smprint("/usr/%s/finger/", user); if (bind(path, "/", MREPL) < 0) { print("unable to bind!\r\n"); syslog(1, LOG, "unable to bind /usr/%s/finger: %r", user); free(path); return; } free(path); chdir("/"); if (!vaccess("finger")){ printnouser(user); return; } if (!cat(file, OREAD)) printnofile(file); } void main(int argc, char **argv) { int n; Biobuf *bin; char *user, *file, *req; ARGBEGIN{ case 'l': puserlist = 0; break; } ARGEND bin = Bfdopen(0, OREAD); req = Brdline(bin, '\n'); if (req == nil){ syslog(1, LOG, "bad read: %r"); sysfatal("bad read: %r"); } n = Blinelen(bin); req[n-1] = 0; n--; if (req[n-1] == '\r'){ req[n-1] = 0; n--; } rfork(RFNAMEG|RFNOMNT); if (vaccess(nsfile)){ if (addns("none", nsfile) < 0){ print("internal error.\r\n"); syslog(1, LOG, "addns failed: %r"); sysfatal("addns failed: %r"); } } switch(n){ case 0: /* null server request */ if (!cat(motd, 0)) print("motd not found.\r\n"); if (puserlist) printuserlist(); break; default: /* non-null request */ file = splitpath(req); user = req; if (strlen(user) <= 0) { printglobalfile(file); break; } printuserfile(user, file); } exits(nil); }