ref: e36ece0f555d55a9ee79ef64a582cd093c41ab2b
dir: /fingerd.c/
#include <u.h> #include <libc.h> #include <auth.h> #include <bio.h> #define BUFSIZ 8192 #define LOG "fingerd" char *nsfile = "/lib/namespace.finger"; char *usernotfound = "/lib/finger/usernotfound"; char *filenotfound = "/lib/finger/filenotfound"; char *motd = "/lib/finger/motd"; char *req; 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); } void main(int argc, char **argv) { int n; Biobuf *bin; char *user, *file, *path; 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--; } 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) { path = smprint("/lib/finger/tree/%s", file); if (!vaccess(path)){ printnofile(file); break; } if (!cat(path, OREAD)) printnofile(file); free(path); break; } path = smprint("/usr/%s/finger/finger", user); if (!vaccess(path)){ printnouser(user); break; } free(path); path = smprint("/usr/%s/finger/%s", user, file); if (!cat(path, OREAD)) printnofile(file); free(path); } exits(nil); }