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);
}