Пример #1
0
void
rmjob(const char *printer)
{
	register int i, nitems;
	int assassinated = 0;
	struct dirent **files;
	char *cp;
	struct printer myprinter, *pp = &myprinter;

	init_printer(pp);
	if ((i = getprintcap(printer, pp)) < 0)
		fatal(pp, "getprintcap: %s", pcaperr(i));
	if ((cp = checkremote(pp))) {
		printf("Warning: %s\n", cp);
		free(cp);
	}

	/*
	 * If the format was `lprm -' and the user isn't the super-user,
	 *  then fake things to look like he said `lprm user'.
	 */
	if (users < 0) {
		if (getuid() == 0)
			all = 1;	/* all files in local queue */
		else {
			user[0] = person;
			users = 1;
		}
	}
	if (!strcmp(person, "-all")) {
		if (from_host == local_host)
			fatal(pp, "The login name \"-all\" is reserved");
		all = 1;	/* all those from 'from_host' */
		person = root;
	}

	seteuid(euid);
	if (chdir(pp->spool_dir) < 0)
		fatal(pp, "cannot chdir to spool directory");
	if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
		fatal(pp, "cannot access spool directory");
	seteuid(uid);

	if (nitems) {
		/*
		 * Check for an active printer daemon (in which case we
		 *  kill it if it is reading our file) then remove stuff
		 *  (after which we have to restart the daemon).
		 */
		if (lockchk(pp, pp->lock_file) && chk(current)) {
			seteuid(euid);
			assassinated = kill(cur_daemon, SIGINT) == 0;
			seteuid(uid);
			if (!assassinated)
				fatal(pp, "cannot kill printer daemon");
		}
		/*
		 * process the files
		 */
		for (i = 0; i < nitems; i++)
			process(pp, files[i]->d_name);
	}
	rmremote(pp);
	/*
	 * Restart the printer daemon if it was killed
	 */
	if (assassinated && !startdaemon(pp))
		fatal(pp, "cannot restart printer daemon\n");
	exit(0);
}
Пример #2
0
void
rmjob(void)
{
	int i, nitems;
	int assassinated = 0;
	struct dirent **files;
	char *cp;

	if ((i = cgetent(&bp, printcapdb, printer)) == -2)
		fatal("can't open printer description file");
	else if (i == -1)
		fatal("unknown printer");
	else if (i == -3)
		fatal("potential reference loop detected in printcap file");
	if (cgetstr(bp, DEFLP, &LP) < 0)
		LP = _PATH_DEFDEVLP;
	if (cgetstr(bp, "rp", &RP) < 0)
		RP = DEFLP;
	if (cgetstr(bp, "sd", &SD) < 0)
		SD = _PATH_DEFSPOOL;
	if (cgetstr(bp,"lo", &LO) < 0)
		LO = DEFLOCK;
	cgetstr(bp, "rm", &RM);
	if ((cp = checkremote()) != NULL)
		printf("Warning: %s\n", cp);

	/*
	 * If the format was `lprm -' and the user isn't the super-user,
	 *  then fake things to look like he said `lprm user'.
	 */
	if (users < 0) {
		if (getuid() == 0)
			all = 1;	/* all files in local queue */
		else {
			user[0] = person;
			users = 1;
		}
	}
	if (!strcmp(person, "-all")) {
		if (from == host)
			fatal("The login name \"-all\" is reserved");
		all = 1;	/* all those from 'from' */
		person = root;
	}

	PRIV_START;
	if (chdir(SD) < 0)
		fatal("cannot chdir to spool directory");
	if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
		fatal("cannot access spool directory");
	PRIV_END;

	if (nitems) {
		/*
		 * Check for an active printer daemon.  If one is running
		 * and it is reading our file, kill it, then remove stuff.
		 * Lastly, restart the daemon if it is not (or no longer)
		 * running.
		 */
		if (lockchk(LO) && chk(current)) {
			PRIV_START;
			assassinated = kill(cur_daemon, SIGINT) == 0;
			PRIV_END;
			if (!assassinated)
				fatal("cannot kill printer daemon");
		}
		/*
		 * process the files
		 */
		for (i = 0; i < nitems; i++)
			process(files[i]->d_name);
	}
	rmremote();
	/*
	 * Restart the printer daemon if it was killed
	 */
	if (assassinated && !startdaemon(printer))
		fatal("cannot restart printer daemon");
	exit(0);
}
Пример #3
0
/*
 * Display the current state of the queue. Format = 1 if long format.
 */
void
displayq(struct printer *pp, int format)
{
	register struct jobqueue *q;
	register int i, nitems, fd, ret;
	char *cp, *endp;
	struct jobqueue **queue;
	struct stat statb;
	FILE *fp;
	void (*savealrm)(int);

	lflag = format;
	totsize = 0;
	rank = -1;

	if ((cp = checkremote(pp))) {
		printf("Warning: %s\n", cp);
		free(cp);
	}

	/*
	 * Print out local queue
	 * Find all the control files in the spooling directory
	 */
	PRIV_START
	if (chdir(pp->spool_dir) < 0)
		fatal(pp, "cannot chdir to spooling directory: %s",
		      strerror(errno));
	PRIV_END
	if ((nitems = getq(pp, &queue)) < 0)
		fatal(pp, "cannot examine spooling area\n");
	PRIV_START
	ret = stat(pp->lock_file, &statb);
	PRIV_END
	if (ret >= 0) {
		if (statb.st_mode & LFM_PRINT_DIS) {
			if (pp->remote)
				printf("%s: ", local_host);
			printf("Warning: %s is down: ", pp->printer);
			PRIV_START
			fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
			PRIV_END
			if (fd >= 0) {
				while ((i = read(fd, line, sizeof(line))) > 0)
					(void) fwrite(line, 1, i, stdout);
				(void) close(fd);	/* unlocks as well */
			} else
				putchar('\n');
		}
		if (statb.st_mode & LFM_QUEUE_DIS) {
			if (pp->remote)
				printf("%s: ", local_host);
			printf("Warning: %s queue is turned off\n", 
			       pp->printer);
		}
	}

	if (nitems) {
		PRIV_START
		fp = fopen(pp->lock_file, "r");
		PRIV_END
		if (fp == NULL)
			daemonwarn(pp);
		else {
			/* get daemon pid */
			cp = current;
			endp = cp + sizeof(current) - 1;
			while ((i = getc(fp)) != EOF && i != '\n') {
				if (cp < endp)
					*cp++ = i;
			}
			*cp = '\0';
			i = atoi(current);
			if (i <= 0) {
				ret = -1;
			} else {
				PRIV_START
				ret = kill(i, 0);
				PRIV_END
			}
			if (ret < 0) {
				daemonwarn(pp);
			} else {
				/* read current file name */
				cp = current;
				endp = cp + sizeof(current) - 1;
				while ((i = getc(fp)) != EOF && i != '\n') {
					if (cp < endp)
						*cp++ = i;
				}
				*cp = '\0';
				/*
				 * Print the status file.
				 */
				if (pp->remote)
					printf("%s: ", local_host);
				PRIV_START
				fd = open(pp->status_file, O_RDONLY|O_SHLOCK);
				PRIV_END
				if (fd >= 0) {
					while ((i = read(fd, line,
							 sizeof(line))) > 0)
						fwrite(line, 1, i, stdout);
					close(fd);	/* unlocks as well */
				} else
					putchar('\n');
			}
			(void) fclose(fp);
		}
		/*
		 * Now, examine the control files and print out the jobs to
		 * be done for each user.
		 */
		if (!lflag)
			header();
		for (i = 0; i < nitems; i++) {
			q = queue[i];
			inform(pp, q->job_cfname);
			free(q);
		}
		free(queue);
	}
	if (!pp->remote) {
		if (nitems == 0)
			puts("no entries");
		return;
	}

	/*
	 * Print foreign queue
	 * Note that a file in transit may show up in either queue.
	 */
	if (nitems)
		putchar('\n');
	(void) snprintf(line, sizeof(line), "%c%s", format ? '\4' : '\3',
			pp->remote_queue);
	cp = line;
	for (i = 0; i < requests && cp-line+10 < sizeof(line) - 1; i++) {
		cp += strlen(cp);
		(void) sprintf(cp, " %d", requ[i]);
	}
	for (i = 0; i < users && cp - line + 1 + strlen(user[i]) < 
		sizeof(line) - 1; i++) {
		cp += strlen(cp);
		*cp++ = ' ';
		(void) strcpy(cp, user[i]);
	}
	strcat(line, "\n");
	savealrm = signal(SIGALRM, alarmhandler);
	alarm(pp->conn_timeout);
	fd = getport(pp, pp->remote_host, 0);
	alarm(0);
	(void)signal(SIGALRM, savealrm);
	if (fd < 0) {
		if (from_host != local_host)
			printf("%s: ", local_host);
		printf("connection to %s is down\n", pp->remote_host);
	}
	else {
		i = strlen(line);
		if (write(fd, line, i) != i)
			fatal(pp, "Lost connection");
		while ((i = read(fd, line, sizeof(line))) > 0)
			filtered_write(line, i, stdout);
		filtered_write(NULL, -1, stdout);
		(void) close(fd);
	}
}
Пример #4
0
/*
 * Display the current state of the queue. Format = 1 if long format.
 */
void
displayq(int format)
{
	struct queue *q;
	int i, rank, nitems, fd, ret, len;
	char *cp, *ecp, *p;
	struct queue **queue;
	struct winsize win;
	struct stat statb;
	FILE *fp;

	termwidth = 80;
	if (isatty(STDOUT_FILENO)) {
		if ((p = getenv("COLUMNS")) != NULL)
			termwidth = atoi(p);
		else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
		    win.ws_col > 0)
			termwidth = win.ws_col;
	}
	if (termwidth < 60)
		termwidth = 60;

	lflag = format;
	totsize = 0;
	if ((i = cgetent(&bp, printcapdb, printer)) == -2)
		fatal("can't open printer description file");
	else if (i == -1)
		fatal("unknown printer");
	else if (i == -3)
		fatal("potential reference loop detected in printcap file");
	if (cgetstr(bp, DEFLP, &LP) < 0)
		LP = _PATH_DEFDEVLP;
	if (cgetstr(bp, "rp", &RP) < 0)
		RP = DEFLP;
	if (cgetstr(bp, "sd", &SD) < 0)
		SD = _PATH_DEFSPOOL;
	if (cgetstr(bp,"lo", &LO) < 0)
		LO = DEFLOCK;
	if (cgetstr(bp, "st", &ST) < 0)
		ST = DEFSTAT;
	cgetstr(bp, "rm", &RM);
	if ((cp = checkremote()) != NULL)
		printf("Warning: %s\n", cp);

	/*
	 * Print out local queue
	 * Find all the control files in the spooling directory
	 */
	PRIV_START;
	if (chdir(SD) < 0)
		fatal("cannot chdir to spooling directory");
	PRIV_END;
	if ((nitems = getq(&queue)) < 0)
		fatal("cannot examine spooling area");
	PRIV_START;
	ret = stat(LO, &statb);
	PRIV_END;
	if (ret >= 0) {
		if (statb.st_mode & S_IXUSR) {
			if (remote)
				printf("%s: ", host);
			printf("Warning: %s is down: ", printer);
			PRIV_START;
			fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0);
			PRIV_END;
			if (fd >= 0 && flock(fd, LOCK_SH) == 0) {
				while ((i = read(fd, line, sizeof(line))) > 0)
					(void)fwrite(line, 1, i, stdout);
				(void)close(fd);	/* unlocks as well */
			} else
				putchar('\n');
		}
		if (statb.st_mode & S_IXGRP) {
			if (remote)
				printf("%s: ", host);
			printf("Warning: %s queue is turned off\n", printer);
		}
	}

	if (nitems) {
		PRIV_START;
		fd = safe_open(LO, O_RDONLY|O_NOFOLLOW, 0);
		PRIV_END;
		if (fd < 0 || (fp = fdopen(fd, "r")) == NULL) {
			if (fd >= 0)
				close(fd);
			nodaemon();
		} else {
			/* get daemon pid */
			cp = current;
			ecp = cp + sizeof(current) - 1;
			while ((i = getc(fp)) != EOF && i != '\n') {
				if (cp < ecp)
					*cp++ = i;
			}
			*cp = '\0';
			i = atoi(current);
			if (i <= 0) {
				ret = -1;
			} else {
				PRIV_START;
				ret = kill(i, 0);
				PRIV_END;
			}
			if (ret < 0 && errno != EPERM) {
				nodaemon();
			} else {
				/* read current file name */
				cp = current;
		    		ecp = cp + sizeof(current) - 1;
				while ((i = getc(fp)) != EOF && i != '\n') {
					if (cp < ecp)
						*cp++ = i;
				}
				*cp = '\0';
				/*
				 * Print the status file.
				 */
				if (remote)
					printf("%s: ", host);
				PRIV_START;
				fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0);
				PRIV_END;
				if (fd >= 0 && flock(fd, LOCK_SH) == 0) {
					while ((i = read(fd, line, sizeof(line))) > 0)
						(void)fwrite(line, 1, i, stdout);
					(void)close(fd);	/* unlocks as well */
				} else
					putchar('\n');
			}
			(void)fclose(fp);
		}
		/*
		 * Now, examine the control files and print out the jobs to
		 * be done for each user.
		 */
		if (!lflag)
			header();
		/* The currently printed job is treated specially. */
		if (!remote && current[0] != '\0')
			inform(current, 0);
		for (i = 0, rank = 1; i < nitems; i++) {
			q = queue[i];
			if (remote || strcmp(current, q->q_name) != 0)
				inform(q->q_name, rank++);
			free(q);
		}
	}
	free(queue);
	if (!remote) {
		if (nitems == 0)
			puts("no entries");
		return;
	}

	/*
	 * Print foreign queue
	 * Note that a file in transit may show up in either queue.
	 */
	if (nitems)
		putchar('\n');
	(void)snprintf(line, sizeof(line), "%c%s", format + '\3', RP);
	cp = line;
	cp += strlen(cp);
	for (i = 0; i < requests && cp - line < sizeof(line) - 1; i++) {
		len = line + sizeof(line) - cp;
		if (snprintf(cp, len, " %d", requ[i]) >= len) {
			cp += strlen(cp);
			break;
		}
		cp += strlen(cp);
	}
	for (i = 0; i < users && cp - line < sizeof(line) - 1; i++) {
		len = line + sizeof(line) - cp;
		if (snprintf(cp, len, " %s", user[i]) >= len) {
			cp += strlen(cp);
			break;
		}
	}
	if (cp-line < sizeof(line) - 1)
		strlcat(line, "\n", sizeof(line));
	else
		line[sizeof(line) - 2] = '\n';
	fd = getport(RM, 0);
	if (fd < 0) {
		if (from != host)
			printf("%s: ", host);
		(void)printf("connection to %s is down\n", RM);
	}
	else {
		struct sigaction osa, nsa;
		char *visline;
		int n = 0;

		i = strlen(line);
		if (write(fd, line, i) != i)
			fatal("Lost connection");
		memset(&nsa, 0, sizeof(nsa));
		nsa.sa_handler = alarmer;
		sigemptyset(&nsa.sa_mask);
		nsa.sa_flags = 0;
		(void)sigaction(SIGALRM, &nsa, &osa);
		alarm(wait_time);
		if ((visline = (char *)malloc(4 * sizeof(line) + 1)) == NULL)
			fatal("Out of memory");
		while ((i = read(fd, line, sizeof(line))) > 0) {
			n = strvisx(visline, line, i, VIS_SAFE|VIS_NOSLASH);
			(void)fwrite(visline, 1, n, stdout);
			alarm(wait_time);
		}
		/* XXX some LPR implementations may not end stream with '\n' */
		if (n > 0 && visline[n-1] != '\n')
			putchar('\n');
		alarm(0);
		(void)sigaction(SIGALRM, &osa, NULL);
		free(visline);
		(void)close(fd);
	}
}