snprintf(pidfile, sizeof pidfile, "%s-%s", PATH_PIDFILE, ipsrc);
main(int argc, char *argv[]){	int lockcnt = 0, pidfd;	FILE *config;	struct in_addr ina;	struct passwd *pw;	char *cp;	uid_t uid;	config = fopen(PATH_CONFFILE, "r");	if (config == NULL)		exit(1);	if ((cp = getenv("SSH_CLIENT")) == NULL) {		syslog(LOG_ERR, "Can't determine connection source");		exit(1);	}	strlcpy(ipsrc, cp, sizeof(ipsrc));	cp = strchr(ipsrc, ' ');	if (!cp) {		syslog(LOG_ERR, "Corrupt SSH_CLIENT variable %s", ipsrc);		exit(1);	}	*cp = '\0';	if (inet_pton(AF_INET, ipsrc, &ina) != 1) {		syslog(LOG_ERR,		    "Cannot determine IP from SSH_CLIENT %s", ipsrc);		exit(1);	}	/* open the pf device */	dev = open(PATH_DEVFILE, O_RDWR);	if (dev == -1) {		syslog(LOG_ERR, "Can't open filter device (%m)");		goto die;	}	uid = getuid();	pw = getpwuid(uid);	if (pw == NULL) {		syslog(LOG_ERR, "can't find user for uid %u", uid);		goto die;	}	if (strcmp(pw->pw_shell, PATH_AUTHPF_SHELL)) {		syslog(LOG_ERR, "wrong shell for user %s, uid %u",		    pw->pw_name, pw->pw_uid);		goto die;	}	strlcpy(luser, pw->pw_name, sizeof(luser));	/* Make our entry in /var/run as /var/run/authpf-ipaddr */	snprintf(pidfile, sizeof pidfile, "%s-%s", PATH_PIDFILE, ipsrc);	/*	 * If someone else is already using this ip, then this person	 * wants to switch users - so kill the old process and exit	 * as well.	 *	 * Note, we could print a message and tell them to log out, but the	 * usual case of this is that someone has left themselves logged in,	 * with the authenticated connection iconized and someone else walks	 * up to use and automatically logs in before using. If this just	 * gets rid of the old one silently, the new user never knows they	 * could have used someone else's old authentication. If we	 * tell them to log out before switching users it is an invitation	 * for abuse.	 */	do {		int save_errno, otherpid = -1;		if ((pidfd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1 ||		    (pidfp = fdopen(pidfd, "r+")) == NULL) {			if (pidfd == -1)				close(pidfd);			syslog(LOG_ERR, "can't open or create %s: %s", pidfile,			    strerror(errno));			goto die;		}		if (flock(fileno(pidfp), LOCK_EX|LOCK_NB) == 0)			break;		save_errno = errno;		rewind(pidfp);		if (fscanf(pidfp, "%d", &otherpid) != 1)			otherpid = -1;		syslog(LOG_DEBUG,		    "Tried to lock %s, in use by pid %d: %s",		    pidfile, otherpid, strerror(save_errno));		if (otherpid > 0) {			syslog(LOG_INFO,			    "killing prior auth (pid %d) of %s by user %s",			    otherpid, ipsrc, luser);			if (kill((pid_t) otherpid, SIGTERM) == -1) {				syslog(LOG_INFO,				    "Couldn't kill process %d: (%m)",				    otherpid);			}		}		/*		 * we try to kill the previous process and acquire the lock		 * for 10 seconds, trying once a second. if we can't after		 * 10 attempts we log an error and give up		 */		if (++lockcnt > 10) {			syslog(LOG_ERR, "Can't kill previous authpf (pid %d)",			    otherpid);			goto dogdeath;		}		sleep(1);		/* re-open, and try again. The previous authpf process		 * we killed above should unlink the file and release		 * it's lock, giving us a chance to get it now		 */		fclose(pidfp);	} while (1);	/*	 * Make an entry in file /var/authpf/ipaddr, containing the username.	 * this lets external applications check for authentication by looking	 * for the ipaddress in that directory, and retrieving the username	 * from it.	 */	snprintf(userfile, sizeof(userfile), "%s/%s", PATH_USERFILE, ipsrc);	if ((ufd = open(userfile, O_CREAT|O_WRONLY, 0640)) == -1) {		syslog(LOG_ERR, "Can't open \"%s\" ! (%m)", userfile);		goto dogdeath;	}	/* revoke privs */	seteuid(getuid());	setuid(getuid());	/*	 * Now we are unable to unlink /var/authpf/$ipsec and /var/run/$pid	 * and instead have to settle for only truncating them.	 */	if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(luser))		do_death(0);	if (read_config(config))		do_death(0);	/* We appear to be making headway, so actually mark our pid */	rewind(pidfp);	fprintf(pidfp, "%ld\n", (long)getpid());	fflush(pidfp);	(void) ftruncate(fileno(pidfp), ftell(pidfp));	write(ufd, luser, strlen(luser));	write(ufd, "\n", 1);	if (changefilter(1, luser, ipsrc) == -1) {		printf("Unable to modify filters\r\n");		do_death(1);	}	signal(SIGTERM, need_death);	signal(SIGINT, need_death);	signal(SIGALRM, need_death);	signal(SIGPIPE, need_death);	signal(SIGHUP, need_death);	signal(SIGSTOP, need_death);	signal(SIGTSTP, need_death);	while (1) {		printf("\r\nHello %s, ", luser);		printf("You are authenticated from host \"%s\"\r\n", ipsrc);		print_message(PATH_MESSAGE);		while (1) {			sleep(10);			if (want_death)				do_death(1);		}	}	/* NOTREACHED */dogdeath:	printf("\r\n\r\nSorry, this service is currently unavailable due to ");	printf("technical difficulties\r\n\r\n");	print_message(PATH_PROBLEM);	printf("\r\nYour authentication process (pid %d) was unable to run\n",	    getpid());	sleep(180); /* them lusers read reaaaaal slow */die:	do_death(0);}