コード例 #1
0
ファイル: pac.c プロジェクト: coyizumi/cs111
/*
 * Perform lookup for printer name or abbreviation --
 */
static int
chkprinter(const char *ptrname)
{
	int stat;
	struct printer myprinter, *pp = &myprinter;

	init_printer(&myprinter);
	stat = getprintcap(ptrname, pp);
	switch(stat) {
	case PCAPERR_OSERR:
		printf("pac: getprintcap: %s\n", pcaperr(stat));
		exit(3);
	case PCAPERR_NOTFOUND:
		return 0;
	case PCAPERR_TCLOOP:
		fatal(pp, "%s", pcaperr(stat));
	}
	if ((acctfile = pp->acct_file) == NULL)
		errx(3, "accounting not enabled for printer %s", ptrname);
	if (!pflag && pp->price100)
		price = pp->price100/10000.0;
	sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5);
	if (sumfile == NULL)
		errx(1, "calloc failed");
	strcpy(sumfile, acctfile);
	strcat(sumfile, "_sum");
	return(1);
}
コード例 #2
0
ファイル: lpc.c プロジェクト: Digital-Chaos/freebsd
/*
 * Routine to get the information for a single printer (which will be
 * called by the routines which implement individual commands).
 * Note: This is for commands operating on a *single* printer.
 */
struct printer *
setup_myprinter(char *pwanted, struct printer *pp, int sump_opts)
{
	int cdres, cmdstatus;

	init_printer(pp);
	cmdstatus = getprintcap(pwanted, pp);
	switch (cmdstatus) {
	default:
		fatal(pp, "%s", pcaperr(cmdstatus));
		/* NOTREACHED */
	case PCAPERR_NOTFOUND:
		printf("unknown printer %s\n", pwanted);
		return (NULL);
	case PCAPERR_TCOPEN:
		printf("warning: %s: unresolved tc= reference(s)", pwanted);
		break;
	case PCAPERR_SUCCESS:
		break;
	}
	if ((sump_opts & SUMP_NOHEADER) == 0)
		printf("%s:\n", pp->printer);

	if (sump_opts & SUMP_CHDIR_SD) {
		PRIV_START
		cdres = chdir(pp->spool_dir);
		PRIV_END
		if (cdres < 0) {
			printf("\tcannot chdir to %s\n", pp->spool_dir);
			free_printer(pp);
			return (NULL);
		}
	}
コード例 #3
0
ファイル: printcap.c プロジェクト: 2asoft/freebsd
/*
 * Free the dynamically-allocated strings in a `struct printer'.
 * Idempotent.
 */
void
free_printer(struct printer *pp)
{
	enum lpd_filters filt;
#define	cfree(x)	do { if (x) free(x); } while(0)
	cfree(pp->printer);
	cfree(pp->acct_file);
	for (filt = 0; filt < LPF_COUNT; filt++)
		cfree(pp->filters[filt]);
	cfree(pp->form_feed);
	cfree(pp->log_file);
	cfree(pp->lock_file);
	cfree(pp->lp);
	cfree(pp->restrict_grp);
	cfree(pp->remote_host);
	cfree(pp->remote_queue);
	cfree(pp->spool_dir);
	cfree(pp->stat_recv);
	cfree(pp->stat_send);
	cfree(pp->status_file);
	cfree(pp->trailer);
	cfree(pp->mode_set);

	init_printer(pp);
}
コード例 #4
0
static void
hrPrinter_get_OS_entries(void)
{
	int  status, more;
	struct printer myprinter, *pp = &myprinter;

	init_printer(pp);
	HRDBG("---->Getting printers .....");
	more = firstprinter(pp, &status);
	if (status)
		goto errloop;

	while (more) {
		do {
			HRDBG("---->Got printer %s", pp->printer);

			handle_printer(pp);
			more = nextprinter(pp, &status);
errloop:
			if (status)
				syslog(LOG_WARNING,
				    "hrPrinterTable: printcap entry for %s "
				    "has errors, skipping",
				    pp->printer ? pp->printer : "<noname?>");
		} while (more && status);
	}

	lastprinter();
	printer_tick = this_tick;
}
コード例 #5
0
/*
 * Initialization:
 * - converter = converter interface (this
 *   is copied into pp->converter).
 * - file = output stream to use (must be an open file)
 * - area = specify display area + truncate + stretch
 *   if area is NULL then the default is used
 * - mode = initial mode
 * - indent = initial indentation (increment)
 *
 * mode + indent are the bottom stack element
 */
void init_pp(pp_t *pp, pp_token_converter_t *converter, FILE *file,
             pp_area_t *area, pp_print_mode_t mode, uint32_t indent) {

  if (area == NULL) {
    area = &default_area;
  }

  assert(area->width >= PP_MINIMAL_WIDTH &&
         area->height >= PP_MINIMAL_HEIGHT);

  init_printer(&pp->printer, file, converter, area, mode, indent);
  init_formatter(&pp->formatter, &pp->printer);
}
コード例 #6
0
ファイル: lpr.c プロジェクト: hmatyschok/MeshBSD
/*
 * Perform lookup for printer name or abbreviation --
 */
static void
chkprinter(const char *ptrname, struct printer *pp)
{
	int status;

	init_printer(pp);
	status = getprintcap(ptrname, pp);
	switch(status) {
	case PCAPERR_OSERR:
	case PCAPERR_TCLOOP:
		errx(1, "%s: %s", ptrname, pcaperr(status));
	case PCAPERR_NOTFOUND:
		errx(1, "%s: unknown printer", ptrname);
	case PCAPERR_TCOPEN:
		warnx("%s: unresolved tc= reference(s)", ptrname);
	}
}
コード例 #7
0
ファイル: main.c プロジェクト: Xeroth95/Astar
int init(struct map_data **map, int argc, char *argv[])
{
	// process tags
	char *map_path;
	if ( argc > 1 )
		map_path = argv[1];
	else
		map_path = "test.map";

	*map = load_map( map_path );
	if (!*map) {
		fprintf(stderr, "Could not open map: %s\n", map_path);
		return 1;
	}

	//construct map
	if (!(*map)->data) {
		fprintf(stderr, "Data got corrupted!\n");
		return 1;
	}


	// init screen
	initscr();
	if((has_color = has_colors()) == FALSE)
	{
		endwin();
		printf("Your terminal does not support color\n");
		return 1;
	} else {
		assert( start_color() );
		assert( init_printer() );
		assert( init_pathfinder( is_traversable_test ) );
		assert( init_keyboard( (*map)->height, (*map)->width-1 ) );
	}

	
	// get keys
	cbreak();
	raw();

	return 0;
}
コード例 #8
0
ファイル: printcap.c プロジェクト: 2asoft/freebsd
/*
 * Scan through the database of printers using cgetfirst/cgetnext.
 * Return false of error or end-of-database; else true.
 */
int
firstprinter(struct printer *pp, int *error)
{
	int status;
	char *bp;

	init_printer(pp);
	status = cgetfirst(&bp, printcapdb);
	if (firstnextmap(&status) == 0) {
		if (error)
			*error = status;
		return 0;
	}
	if (error)
		*error = status;
	status = getprintcap_int(bp, pp);
	free(bp);
	if (error && status)
		*error = status;
	return 1;
}
コード例 #9
0
ファイル: printd.c プロジェクト: BigR-Lab/CodeRes_Cpp
/*
 * Main print server thread.  Accepts connect requests from
 * clients and spawns additional threads to service requests.
 *
 * LOCKING: none.
 */
int
main(int argc, char *argv[])
{
	pthread_t			tid;
	struct addrinfo		*ailist, *aip;
	int					sockfd, err, i, n, maxfd;
	char				*host;
	fd_set				rendezvous, rset;
	struct sigaction	sa;
	struct passwd		*pwdp;

	if (argc != 1)
		err_quit("usage: printd");
	daemonize("printd");

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &sa, NULL) < 0)
		log_sys("sigaction failed");
	sigemptyset(&mask);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGTERM);
	if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
		log_sys("pthread_sigmask failed");

	n = sysconf(_SC_HOST_NAME_MAX);
	if (n < 0)	/* best guess */
		n = HOST_NAME_MAX;
	if ((host = malloc(n)) == NULL)
		log_sys("malloc error");
	if (gethostname(host, n) < 0)
		log_sys("gethostname error");

	if ((err = getaddrlist(host, "print", &ailist)) != 0) {
		log_quit("getaddrinfo error: %s", gai_strerror(err));
		exit(1);
	}
	FD_ZERO(&rendezvous);
	maxfd = -1;
	for (aip = ailist; aip != NULL; aip = aip->ai_next) {
		if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr,
		  aip->ai_addrlen, QLEN)) >= 0) {
			FD_SET(sockfd, &rendezvous);
			if (sockfd > maxfd)
				maxfd = sockfd;
		}
	}
	if (maxfd == -1)
		log_quit("service not enabled");

	pwdp = getpwnam(LPNAME);
	if (pwdp == NULL)
		log_sys("can't find user %s", LPNAME);
	if (pwdp->pw_uid == 0)
		log_quit("user %s is privileged", LPNAME);
	if (setgid(pwdp->pw_gid) < 0 || setuid(pwdp->pw_uid) < 0)
		log_sys("can't change IDs to user %s", LPNAME);

	init_request();
	init_printer();

	err = pthread_create(&tid, NULL, printer_thread, NULL);
	if (err == 0)
		err = pthread_create(&tid, NULL, signal_thread, NULL);
	if (err != 0)
		log_exit(err, "can't create thread");
	build_qonstart();

	log_msg("daemon initialized");

	for (;;) {
		rset = rendezvous;
		if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0)
			log_sys("select failed");
		for (i = 0; i <= maxfd; i++) {
			if (FD_ISSET(i, &rset)) {
				/*
				 * Accept the connection and handle the request.
				 */
				if ((sockfd = accept(i, NULL, NULL)) < 0)
					log_ret("accept failed");
				pthread_create(&tid, NULL, client_thread,
				  (void *)((long)sockfd));
			}
		}
	}
	exit(1);
}
コード例 #10
0
ファイル: printd.c プロジェクト: BigR-Lab/CodeRes_Cpp
/*
 * Single thread to communicate with the printer.
 *
 * LOCKING: acquires and releases joblock and configlock.
 */
void *
printer_thread(void *arg)
{
	struct job		*jp;
	int				hlen, ilen, sockfd, fd, nr, nw, extra;
	char			*icp, *hcp, *p;
	struct ipp_hdr	*hp;
	struct stat		sbuf;
	struct iovec	iov[2];
	char			name[FILENMSZ];
	char			hbuf[HBUFSZ];
	char			ibuf[IBUFSZ];
	char			buf[IOBUFSZ];
	char			str[64];
	struct timespec	ts = { 60, 0 };		/* 1 minute */

	for (;;) {
		/*
		 * Get a job to print.
		 */
		pthread_mutex_lock(&joblock);
		while (jobhead == NULL) {
			log_msg("printer_thread: waiting...");
			pthread_cond_wait(&jobwait, &joblock);
		}
		remove_job(jp = jobhead);
		log_msg("printer_thread: picked up job %d", jp->jobid);
		pthread_mutex_unlock(&joblock);
		update_jobno();

		/*
		 * Check for a change in the config file.
		 */
		pthread_mutex_lock(&configlock);
		if (reread) {
			freeaddrinfo(printer);
			printer = NULL;
			printer_name = NULL;
			reread = 0;
			pthread_mutex_unlock(&configlock);
			init_printer();
		} else {
			pthread_mutex_unlock(&configlock);
		}

		/*
		 * Send job to printer.
		 */
		sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jp->jobid);
		if ((fd = open(name, O_RDONLY)) < 0) {
			log_msg("job %d canceled - can't open %s: %s",
			  jp->jobid, name, strerror(errno));
			free(jp);
			continue;
		}
		if (fstat(fd, &sbuf) < 0) {
			log_msg("job %d canceled - can't fstat %s: %s",
			  jp->jobid, name, strerror(errno));
			free(jp);
			close(fd);
			continue;
		}
		if ((sockfd = connect_retry(AF_INET, SOCK_STREAM, 0,
		  printer->ai_addr, printer->ai_addrlen)) < 0) {
			log_msg("job %d deferred - can't contact printer: %s",
			  jp->jobid, strerror(errno));
			goto defer;
		}

		/*
		 * Set up the IPP header.
		 */
		icp = ibuf;
		hp = (struct ipp_hdr *)icp;
		hp->major_version = 1;
		hp->minor_version = 1;
		hp->operation = htons(OP_PRINT_JOB);
		hp->request_id = htonl(jp->jobid);
		icp += offsetof(struct ipp_hdr, attr_group);
		*icp++ = TAG_OPERATION_ATTR;
		icp = add_option(icp, TAG_CHARSET, "attributes-charset",
		  "utf-8");
		icp = add_option(icp, TAG_NATULANG,
		  "attributes-natural-language", "en-us");
		sprintf(str, "http://%s/ipp", printer_name);
		icp = add_option(icp, TAG_URI, "printer-uri", str);
		icp = add_option(icp, TAG_NAMEWOLANG,
		  "requesting-user-name", jp->req.usernm);
		icp = add_option(icp, TAG_NAMEWOLANG, "job-name",
		  jp->req.jobnm);
		if (jp->req.flags & PR_TEXT) {
			p = "text/plain";
			extra = 1;
		} else {
			p = "application/postscript";
			extra = 0;
		}
		icp = add_option(icp, TAG_MIMETYPE, "document-format", p);
		*icp++ = TAG_END_OF_ATTR;
		ilen = icp - ibuf;

		/*
		 * Set up the HTTP header.
		 */
		hcp = hbuf;
		sprintf(hcp, "POST /ipp HTTP/1.1\r\n");
		hcp += strlen(hcp);
		sprintf(hcp, "Content-Length: %ld\r\n",
		  (long)sbuf.st_size + ilen + extra);
		hcp += strlen(hcp);
		strcpy(hcp, "Content-Type: application/ipp\r\n");
		hcp += strlen(hcp);
		sprintf(hcp, "Host: %s:%d\r\n", printer_name, IPP_PORT);
		hcp += strlen(hcp);
		*hcp++ = '\r';
		*hcp++ = '\n';
		hlen = hcp - hbuf;

		/*
		 * Write the headers first.  Then send the file.
		 */
		iov[0].iov_base = hbuf;
		iov[0].iov_len = hlen;
		iov[1].iov_base = ibuf;
		iov[1].iov_len = ilen;
		if (writev(sockfd, iov, 2) != hlen + ilen) {
			log_ret("can't write to printer");
			goto defer;
		}

		if (jp->req.flags & PR_TEXT) {
			/*
			 * Hack: allow PostScript to be printed as plain text.
			 */
			if (write(sockfd, "\b", 1) != 1) {
				log_ret("can't write to printer");
				goto defer;
			}
		}

		while ((nr = read(fd, buf, IOBUFSZ)) > 0) {
			if ((nw = writen(sockfd, buf, nr)) != nr) {
				if (nw < 0)
				  log_ret("can't write to printer");
				else
				  log_msg("short write (%d/%d) to printer", nw, nr);
				goto defer;
			}
		}
		if (nr < 0) {
			log_ret("can't read %s", name);
			goto defer;
		}

		/*
		 * Read the response from the printer.
		 */
		if (printer_status(sockfd, jp)) {
			unlink(name);
			sprintf(name, "%s/%s/%d", SPOOLDIR, REQDIR, jp->jobid);
			unlink(name);
			free(jp);
			jp = NULL;
		}
defer:
		close(fd);
		if (sockfd >= 0)
			close(sockfd);
		if (jp != NULL) {
			replace_job(jp);
			nanosleep(&ts, NULL);
		}
	}
}
コード例 #11
0
ファイル: rmjob.c プロジェクト: AhmadTux/freebsd
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);
}
コード例 #12
0
ファイル: lpq.c プロジェクト: mihaicarabas/dragonfly
int
main(int argc, char **argv)
{
	int ch, aflag, lflag;
	const char *printer;
	struct printer myprinter, *pp = &myprinter;

	printer = NULL;
	euid = geteuid();
	uid = getuid();
	seteuid(uid);
	progname = *argv;
	if (gethostname(local_host, sizeof(local_host)))
		err(1, "gethostname");
	openlog("lpd", 0, LOG_LPR);

	aflag = lflag = 0;
	while ((ch = getopt(argc, argv, "alP:")) != -1)
		switch((char)ch) {
		case 'a':
			++aflag;
			break;
		case 'l':			/* long output */
			++lflag;
			break;
		case 'P':		/* printer name */
			printer = optarg;
			break;
		case '?':
		default:
			usage();
		}

	if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
		printer = DEFLP;

	for (argc -= optind, argv += optind; argc; --argc, ++argv)
		if (isdigit(argv[0][0])) {
			if (requests >= MAXREQUESTS)
				fatal(0, "too many requests");
			requ[requests++] = atoi(*argv);
		}
		else {
			if (users >= MAXUSERS)
				fatal(0, "too many users");
			user[users++] = *argv;
		}

	if (aflag) {
		int more, status;

		more = firstprinter(pp, &status);
		if (status)
			goto looperr;
		while (more) {
			if (ckqueue(pp) > 0) {
				printf("%s:\n", pp->printer);
				displayq(pp, lflag);
				printf("\n");
			}
			do {
				more = nextprinter(pp, &status);
looperr:
				switch (status) {
				case PCAPERR_TCOPEN:
					printf("warning: %s: unresolved "
					       "tc= reference(s) ",
					       pp->printer);
				case PCAPERR_SUCCESS:
					break;
				default:
					fatal(pp, "%s", pcaperr(status));
				}
			} while (more && status);
		}
	} else {
		int status;

		init_printer(pp);
		status = getprintcap(printer, pp);
		if (status < 0)
			fatal(pp, "%s", pcaperr(status));

		displayq(pp, lflag);
	}
	exit(0);
}
コード例 #13
0
ファイル: cmds.c プロジェクト: edgar-pek/PerspicuOS
void
generic(void (*specificrtn)(struct printer *_pp), int cmdopts,
    void (*initrtn)(int _argc, char *_argv[]), int argc, char *argv[])
{
	int cmdstatus, more, targc;
	struct printer myprinter, *pp;
	char **margv, **targv;

	if (argc == 1) {
		/*
		 * Usage needs a special case for 'down': The user must
		 * either include `-msg', or only the first parameter
		 * that they give will be processed as a printer name.
		 */
		printf("usage: %s  {all | printer ...}", argv[0]);
		if (strcmp(argv[0], "down") == 0) {
			printf(" -msg [<text> ...]\n");
			printf("   or: down  {all | printer} [<text> ...]");
		} else if (cmdopts & LPC_MSGOPT)
			printf(" [-msg <text> ...]");
		printf("\n");
		return;
	}

	/* The first argument is the command name. */
	generic_cmdname = *argv++;
	argc--;

	/*
	 * The initialization routine for a command might set a generic
	 * "wrapup" routine, which should be called after processing all
	 * the printers in the command.  This might print summary info.
	 *
	 * Note that the initialization routine may also parse (and
	 * nullify) some of the parameters given on the command, leaving
	 * only the parameters which have to do with printer names.
	 */
	pp = &myprinter;
	generic_wrapup = NULL;
	generic_qselect = QSEL_UNKNOWN;
	cmdstatus = 0;
	/* this just needs to be a distinct value of type 'char *' */
	if (generic_nullarg == NULL)
		generic_nullarg = strdup("");

	/*
	 * Some commands accept a -msg argument, which indicates that
	 * all remaining arguments should be combined into a string.
	 */
	generic_msg = NULL;
	if (cmdopts & LPC_MSGOPT) {
		targc = argc;
		targv = argv;
		for (; targc > 0; targc--, targv++) {
			if (strcmp(*targv, "-msg") == 0) {
				argc -= targc;
				generic_msg = args2line(targc - 1, targv + 1);
				break;
			}
		}
	}

	/* call initialization routine, if there is one for this cmd */
	if (initrtn != NULL) {
		generic_initerr = 0;
		(*initrtn)(argc, argv);
		if (generic_initerr)
			return;
		/*
		 * The initrtn may have null'ed out some of the parameters.
		 * Compact the parameter list to remove those nulls, and
		 * correct the arg-count.
		 */
		targc = argc;
		targv = argv;
		margv = argv;
		argc = 0;
		for (; targc > 0; targc--, targv++) {
			if (*targv != generic_nullarg) {
				if (targv != margv)
					*margv = *targv;
				margv++;
				argc++;
			}
		}
	}

	if (argc == 1 && strcmp(*argv, "all") == 0) {
		generic_qselect = QSEL_ALL;
		more = firstprinter(pp, &cmdstatus);
		if (cmdstatus)
			goto looperr;
		while (more) {
			(*specificrtn)(pp);
			do {
				more = nextprinter(pp, &cmdstatus);
looperr:
				switch (cmdstatus) {
				case PCAPERR_TCOPEN:
					printf("warning: %s: unresolved "
					       "tc= reference(s) ",
					       pp->printer);
				case PCAPERR_SUCCESS:
					break;
				default:
					fatal(pp, "%s", pcaperr(cmdstatus));
				}
			} while (more && cmdstatus);
		}
		goto wrapup;
	}

	generic_qselect = QSEL_BYNAME;		/* specifically-named ptrs */
	for (; argc > 0; argc--, argv++) {
		init_printer(pp);
		cmdstatus = getprintcap(*argv, pp);
		switch (cmdstatus) {
		default:
			fatal(pp, "%s", pcaperr(cmdstatus));
		case PCAPERR_NOTFOUND:
			printf("unknown printer %s\n", *argv);
			continue;
		case PCAPERR_TCOPEN:
			printf("warning: %s: unresolved tc= reference(s)\n",
			       *argv);
			break;
		case PCAPERR_SUCCESS:
			break;
		}
		(*specificrtn)(pp);
	}

wrapup:
	if (generic_wrapup) {
		(*generic_wrapup)(cmdstatus);
	}
	free_printer(pp);
	if (generic_msg)
		free(generic_msg);
}
コード例 #14
0
static void
doit(void)
{
	char *cp, *printer;
	int n;
	int status;
	struct printer myprinter, *pp = &myprinter;

	init_printer(&myprinter);

	for (;;) {
		cp = cbuf;
		do {
			if (cp >= &cbuf[sizeof(cbuf) - 1])
				fatal(0, "Command line too long");
			if ((n = read(STDOUT_FILENO, cp, 1)) != 1) {
				if (n < 0)
					fatal(0, "Lost connection");
				return;
			}
		} while (*cp++ != '\n');
		*--cp = '\0';
		cp = cbuf;
		if (lflag) {
			if (*cp >= '\1' && *cp <= '\5')
				syslog(LOG_INFO, "%s requests %s %s",
					from_host, cmdnames[(u_char)*cp], cp+1);
			else
				syslog(LOG_INFO, "bad request (%d) from %s",
					*cp, from_host);
		}
		switch (*cp++) {
		case CMD_CHECK_QUE: /* check the queue, print any jobs there */
			startprinting(cp);
			break;
		case CMD_TAKE_THIS: /* receive files to be queued */
			if (!from_remote) {
				syslog(LOG_INFO, "illegal request (%d)", *cp);
				exit(1);
			}
			recvjob(cp);
			break;
		case CMD_SHOWQ_SHORT: /* display the queue (short form) */
		case CMD_SHOWQ_LONG: /* display the queue (long form) */
			/* XXX - this all needs to be redone. */
			printer = cp;
			while (*cp) {
				if (*cp != ' ') {
					cp++;
					continue;
				}
				*cp++ = '\0';
				while (isspace(*cp))
					cp++;
				if (*cp == '\0')
					break;
				if (isdigit(*cp)) {
					if (requests >= MAXREQUESTS)
						fatal(0, "Too many requests");
					requ[requests++] = atoi(cp);
				} else {
					if (users >= MAXUSERS)
						fatal(0, "Too many users");
					user[users++] = cp;
				}
			}
			status = getprintcap(printer, pp);
			if (status < 0)
				fatal(pp, "%s", pcaperr(status));
			displayq(pp, cbuf[0] == CMD_SHOWQ_LONG);
			exit(0);
		case CMD_RMJOB:	/* remove a job from the queue */
			if (!from_remote) {
				syslog(LOG_INFO, "illegal request (%d)", *cp);
				exit(1);
			}
			printer = cp;
			while (*cp && *cp != ' ')
				cp++;
			if (!*cp)
				break;
			*cp++ = '\0';
			person = cp;
			while (*cp) {
				if (*cp != ' ') {
					cp++;
					continue;
				}
				*cp++ = '\0';
				while (isspace(*cp))
					cp++;
				if (*cp == '\0')
					break;
				if (isdigit(*cp)) {
					if (requests >= MAXREQUESTS)
						fatal(0, "Too many requests");
					requ[requests++] = atoi(cp);
				} else {
					if (users >= MAXUSERS)
						fatal(0, "Too many users");
					user[users++] = cp;
				}
			}
			rmjob(printer);
			break;
		}
		fatal(0, "Illegal service request");
	}
}