shithub: fingerd

ref: 83e52dcb1e1099ae9ac735ac4fead6aa99693c79
dir: /fingerd.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>

#define BUFSIZ 8192

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(usernotfound, 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, '\r');
	if (req == nil)
		sysfatal("bad read: %r");
	n = Blinelen(bin);
	req[n-1] = 0;

	switch(n){
	case 1:  /* server request */
		if (!cat(motd, 0))
			print("motd not found.\r\n");
		if (puserlist)
			printuserlist();
		break;
	default: /* user request   */
		file = splitpath(req);
		user = req;
		if (strlen(user) <= 0) {
			print("bad request.\n");
			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);
	}
}