/* userlist.c - look up the current user in a userlist
 */

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include "bbs.h"


extern char *menu_file;			 /* current menu */


/* Return 1 if the current user is part of the userlist file "list", 0 if not.
 *
 * A menu can only use listfiles belonging to the owner of that menu, plus
 * system lists. So a menu owned by "user1" referencing "user2/foolist" will
 * always return 0.
 */
int hook_usercheck(char *list)
{
	struct passwd *z;
	struct stat sb;
	struct stat sc;
	char buf[1024];
	FILE *fptr;
	char *a;
	int t = 0;
	int l;

	strncpy(buf, list, sizeof(buf) - 1);
	buf[sizeof(buf) - 1] = 0;

	a = strchr(buf, '/');
	if (!a)
		return (0);		    /* no / - not a userlist */
	a[0] = 0;

	if (a[1] != 0) {		    /* foo/bar - user "foo", file "bar" */
		if (stat(menu_file, &sb))
			return (0);
		z = getpwuid(sb.st_uid);
		if (!z)
			return (0);
		if (strcmp(z->pw_name, buf))
			return (0);	    /* different owner */
		a = cf_str("usrlist");	    /* file is in usrlist dir */
		t = 1;
	} else {			    /* foo/ - system list file "foo" */
		a = cf_str("listdir");	    /* file is in sysgroup dir */
	}

	strncpy(buf, a, sizeof(buf) - 1);
	strcat(buf, "/");
	strncat(buf, list, sizeof(buf) - 1 - strlen(buf));
	a = buf + strlen(buf) - 1;
	if (a < buf)
		return (0);
	while ((a[0] == '/') && (strlen(buf) > 0)) {	/* strip trailing /'s */
		a[0] = 0;
		a--;
	}

	if (t) {			    /* user file - check ownership */
		if (stat(buf, &sc))
			return (0);	    /* failed to stat file */
		if (sb.st_uid != sc.st_uid)
			return (0);	    /* not owned by menu owner */
	}

	fptr = fopen(buf, "r");		    /* open list file for reading */
	if (!fptr)
		return (0);

	while ((!feof(fptr)) && (!ferror(fptr))) {
		buf[0] = 0;
		fgets(buf, sizeof(buf) - 1, fptr);	/* read line */
		buf[sizeof(buf) - 1] = 0;
		a = strchr(buf, '\n');	    /* chop \n */
		if (a)
			*a = 0;
		if (buf[0] == 0)
			continue;	    /* skip blank lines */
		a = buf;
		while (a[0] != 0) {	    /* many names per line, so split */
			while ((a[0] == ' ') || (a[0] == '\011'))
				a++;
			if (a[0] == 0)
				continue;
			l = strcspn(a, " \011");
			if (l < 1) {
				a[0] = 0;
				continue;
			}
			if (a[0] == '#') {  /* stop at a comment */
				a[0] = 0;
				continue;
			}
			if ((strlen(current_user) == l) && (!strncmp(a, current_user, l))) {	/* matched name */
				fclose(fptr);
				return (1);
			}
			a += l;
		}
	}

	fclose(fptr);
	return (0);
}

/* EOF */
