xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/status.c (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright (c) 2001 by Sun Microsystems, Inc.
28  * All rights reserved.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include "stdlib.h"
34 #include "string.h"
35 #include "unistd.h"
36 #include <syslog.h>
37 
38 #include "lpsched.h"
39 
40 #define NCMP(X,Y)	(STRNEQU((X), (Y), sizeof(Y)-1))
41 
42 extern char *LP_TRAY_UNMOUNT;
43 
44 static void		load_pstatus ( void );
45 static void		load_fault_status ( void );
46 static void		load_cstatus ( void );
47 static void		put_multi_line ( int , char * );
48 static PFSTATUS * parseFormList ( char *,short *);
49 static void markFormsMounted( PSTATUS *);
50 
51 
52 #define FAULT_MESSAGE_FILE "faultMessage"
53 static char		*pstatus	= 0,
54 			*cstatus	= 0;
55 
56 /**
57  ** load_status() - LOAD PRINTER/CLASS STATUS FILES
58  **/
59 
60 void
61 load_status(void)
62 {
63 	load_pstatus ();
64 
65 	load_cstatus ();
66 	load_fault_status ();
67 	return;
68 }
69 
70 /**
71  ** load_pstatus() - LOAD PRITNER STATUS FILE
72  **/
73 
74 static void
75 load_pstatus(void)
76 {
77 	PSTATUS			*pps;
78 
79 	char			*rej_reason,
80 				*dis_reason,
81 				*pwheel_name,
82 				buf[BUFSIZ],
83 				*name,
84 				*p;
85 
86 	time_t			rej_date,
87 				dis_date;
88 
89 	short			status;
90 
91 	PFSTATUS		*ppfs;
92 
93 	PWSTATUS		*ppws;
94 
95 	int			i,
96 				len,
97 				total;
98 
99 	time_t			now;
100 
101 	int fd;
102 
103 	register int		f;
104 	short			numForms;
105 
106 
107 	(void) time(&now);
108 
109 	if (!pstatus)
110 		pstatus = makepath(Lp_System, PSTATUSFILE, (char *)0);
111 	if ((fd = open_locked(pstatus, "r", 0)) >= 0) {
112 		char *tmp = pstatus; /* not NULL */
113 
114 		while (tmp != NULL) {
115 			status = 0;
116 			total = 0;
117 			name = 0;
118 			rej_reason = 0;
119 			dis_reason = 0;
120 			ppfs = 0;
121 
122 			errno = 0;
123 			for (f = 0;
124 			    (f < PST_MAX) && (tmp = fdgets(buf, BUFSIZ, fd));
125 			    f++) {
126 				if (p = strrchr(buf, '\n'))
127 					*p = '\0';
128 
129 				switch (f) {
130 				case PST_BRK:
131 					break;
132 
133 				case PST_NAME:
134 					name = Strdup(buf);
135 					break;
136 
137 				case PST_STATUS:
138 					if (NCMP(buf, NAME_DISABLED))
139 						status |= PS_DISABLED;
140 					p = strchr(buf, ' ');
141 					if (!p || !*(++p))
142 						break;
143 					if (NCMP(p, NAME_REJECTING))
144 						status |= PS_REJECTED;
145 					break;
146 
147 				case PST_DATE:
148 					dis_date = (time_t)atol(buf);
149 					p = strchr(buf, ' ');
150 					if (!p || !*(++p))
151 						break;
152 					rej_date = (time_t)atol(p);
153 					break;
154 
155 				case PST_DISREAS:
156 					len = strlen(buf);
157 					if (buf[len - 1] == '\\') {
158 						buf[len - 1] = '\n';
159 						f--;
160 					}
161 					if (dis_reason) {
162 						total += len;
163 						dis_reason = Realloc(
164 							dis_reason,
165 							total+1
166 						);
167 						strcat (dis_reason, buf);
168 					} else {
169 						dis_reason = Strdup(buf);
170 						total = len;
171 					}
172 					break;
173 
174 				case PST_REJREAS:
175 					len = strlen(buf);
176 					if (buf[len - 1] == '\\') {
177 						buf[len - 1] = '\n';
178 						f--;
179 					}
180 					if (rej_reason) {
181 						total += len;
182 						rej_reason = Realloc(
183 							rej_reason,
184 							total+1
185 						);
186 						strcat (rej_reason, buf);
187 					} else {
188 						rej_reason = Strdup(buf);
189 						total = len;
190 					}
191 					break;
192 
193 				case PST_PWHEEL:
194 					if (*buf) {
195 						ppws = search_pwtable(buf);
196 						pwheel_name = Strdup(buf);
197 					} else {
198 						ppws = 0;
199 						pwheel_name = 0;
200 					}
201 					break;
202 
203 				case PST_FORM:
204 					ppfs = parseFormList (buf,&numForms);
205 					break;
206 				}
207 			}
208 
209 			if ((errno != 0) || f && f != PST_MAX) {
210 				close(fd);
211 				note("Had trouble reading file %s", pstatus);
212 				return;
213 			}
214 
215 			if ((tmp != NULL) && name &&
216 			    (pps = search_ptable(name))) {
217 				pps->rej_date = rej_date;
218 				pps->status |= status;
219 				pps->forms = ppfs;
220 				if (ppfs) markFormsMounted(pps);
221 				pps->numForms = numForms;
222 				pps->pwheel_name = pwheel_name;
223 				if ((pps->pwheel = ppws) != NULL)
224 					ppws->mounted++;
225 				pps->rej_reason = rej_reason;
226 				load_str(&pps->fault_reason, CUZ_PRINTING_OK);
227 				if (pps->printer->login) {
228 					pps->dis_date = now;
229 					pps->dis_reason =
230 						Strdup(CUZ_LOGIN_PRINTER);
231 				} else {
232 					pps->dis_date = dis_date;
233 					pps->dis_reason = dis_reason;
234 				}
235 
236 			} else {
237 				if (ppfs)
238 					Free(ppfs);
239 				if (dis_reason)
240 					Free (dis_reason);
241 				if (rej_reason)
242 					Free (rej_reason);
243 			}
244 			if (name)
245 				Free (name);
246 		}
247 	}
248 
249 	if (fd >= 0) {
250 		if (errno != 0) {
251 			close(fd);
252 			note("Had trouble reading file %s", pstatus);
253 			return;
254 		}
255 		close(fd);
256 	}
257 
258 	for (i = 0; i < PT_Size; i++)
259 		if (PStatus[i].printer->name && !PStatus[i].rej_reason) {
260 			PStatus[i].dis_reason = Strdup(CUZ_NEW_PRINTER);
261 			PStatus[i].rej_reason = Strdup(CUZ_NEW_DEST);
262 			PStatus[i].fault_reason = Strdup(CUZ_PRINTING_OK);
263 			PStatus[i].dis_date = now;
264 			PStatus[i].rej_date = now;
265 			PStatus[i].status |= PS_DISABLED | PS_REJECTED;
266 		}
267 
268 	return;
269 }
270 
271 /**
272  ** load_fault_status() - LOAD PRITNER Fault STATUS FILE
273  **/
274 
275 static void
276 load_fault_status(void)
277 {
278 	PSTATUS			*pps;
279 
280 	char			*fault_reason = NULL,
281 				buf[BUFSIZ],
282 				*fault_status,
283 				*printerName,
284 				*p;
285 
286 	int			i,
287 				len,
288 				total;
289 
290 
291 	int fd;
292 
293 	for (i = 0; i < PT_Size; i++) {
294 		printerName = PStatus[i].printer->name;
295 		if (printerName) {
296 			fault_status = makepath(Lp_A_Printers, printerName,
297 				FAULT_MESSAGE_FILE , (char *) 0);
298 			fault_reason = NULL;
299 			total = 0;
300 
301 			if ((fd = open_locked(fault_status, "r", 0)) >= 0) {
302 				while (fdgets(buf, BUFSIZ, fd)) {
303 					len = strlen(buf);
304 					if (fault_reason) {
305 						total += len;
306 						fault_reason =
307 							Realloc(fault_reason,
308 								total+1);
309 						strcat (fault_reason, buf);
310 					} else {
311 						fault_reason = Strdup(buf);
312 						total = len;
313 					}
314 				}
315 
316 				if (fault_reason &&
317 				    (pps = search_ptable(printerName))) {
318 					p = fault_reason + strlen(fault_reason)
319 						- 1;
320 					if (*p == '\n')
321 						*p = 0;
322 					load_str(&pps->fault_reason,
323 						fault_reason);
324 				}
325 				if (fault_reason)
326 					Free(fault_reason);
327 
328 				close(fd);
329 			}
330 			Free(fault_status);
331 		}
332 	}
333 }
334 
335 
336 /**
337  ** load_cstatus() - LOAD CLASS STATUS FILE
338  **/
339 
340 static void
341 load_cstatus(void)
342 {
343 	CSTATUS			*pcs;
344 	char			*rej_reason,
345 				buf[BUFSIZ],
346 				*name,
347 				*p;
348 	time_t			rej_date;
349 	short			status;
350 	int			i,
351 				len,
352 				total;
353 	time_t			now;
354 	int fd;
355 	register int		f;
356 
357 
358 	(void) time(&now);
359 
360 	if (!cstatus)
361 		cstatus = makepath(Lp_System, CSTATUSFILE, (char *)0);
362 
363 	if ((fd = open_locked(cstatus, "r", 0)) >= 0) {
364 		char *tmp = cstatus; /* not NULL */
365 
366 		errno = 0;
367 		while (tmp != NULL) {
368 			status = 0;
369 
370 			total = 0;
371 			name = 0;
372 
373 			rej_reason = 0;
374 			for (f = 0;
375 			    (f < CST_MAX) && (tmp = fdgets(buf, BUFSIZ, fd));
376 			    f++) {
377 				if (p = strrchr(buf, '\n'))
378 					*p = '\0';
379 				switch (f) {
380 				case CST_BRK:
381 					break;
382 
383 				case CST_NAME:
384 					name = Strdup(buf);
385 					break;
386 
387 				case CST_STATUS:
388 					if (NCMP(buf, NAME_REJECTING))
389 						status |= PS_REJECTED;
390 					break;
391 
392 				case CST_DATE:
393 					rej_date = (time_t)atol(buf);
394 					break;
395 
396 				case CST_REJREAS:
397 					len = strlen(buf);
398 					if (buf[len - 1] == '\\') {
399 						buf[len - 1] = '\n';
400 						f--;
401 					}
402 					if (rej_reason) {
403 						total += len;
404 						rej_reason = Realloc(
405 							rej_reason,
406 							total+1
407 						);
408 						strcat (rej_reason, buf);
409 					} else {
410 						rej_reason = Strdup(buf);
411 						total = len;
412 					}
413 					break;
414 				}
415 			}
416 
417 			if ((errno != 0) || f && f != CST_MAX) {
418 				close(fd);
419 				note("Had trouble reading file %s", cstatus);
420 				return;
421 			}
422 
423 			if ((tmp != NULL) && name &&
424 			    (pcs = search_ctable(name))) {
425 				pcs->rej_reason = rej_reason;
426 				pcs->rej_date = rej_date;
427 				pcs->status |= status;
428 
429 			} else
430 				if (rej_reason)
431 					Free (rej_reason);
432 
433 			if (name)
434 				Free (name);
435 		}
436 	}
437 
438 	if (fd >= 0) {
439 		if (errno != 0) {
440 			close(fd);
441 			note("Had trouble reading file %s", cstatus);
442 			return;
443 		}
444 		close(fd);
445 	}
446 
447 	for (i = 0; i < CT_Size; i++)
448 		if (CStatus[i].class->name && !CStatus[i].rej_reason) {
449 			CStatus[i].status |= CS_REJECTED;
450 			CStatus[i].rej_reason = Strdup(CUZ_NEW_DEST);
451 			CStatus[i].rej_date = now;
452 		}
453 
454 	return;
455 }
456 
457 /**
458  ** showForms()
459  **/
460 char *
461 showForms(PSTATUS  *pps)
462 {
463 	int i;
464 	char			*formList = NULL;
465 	char buf[100];
466 	FSTATUS *pfs;
467 	PFSTATUS  *ppfs;
468 	short numForms;
469 
470 	numForms = pps->numForms;
471 	ppfs = pps->forms;
472 	if (ppfs) {
473 		for (i = 0; i < numForms; i++) {
474 			pfs = ppfs[i].form;
475 			snprintf(buf, sizeof (buf), "%s%c",
476 				(pfs ? pfs->form->name : ""), *LP_SEP);
477 
478 			if (addstring(&formList,buf)) { /* allocation failed */
479 				if (formList) {
480 					Free(formList);
481 					formList = NULL;
482 				}
483 				return(NULL);
484 			}
485 		}
486 	}
487 	return(formList);
488 }
489 
490 /**
491  ** markFormsMounted()
492  **/
493 
494 void
495 markFormsMounted(PSTATUS *pps)
496 {
497 	int i;
498 	int numTrays;
499 	PFSTATUS *ppfs;
500 	FSTATUS *pfs;
501 
502 
503 	ppfs = pps->forms;
504 	if (ppfs) {
505 		numTrays = pps->numForms;
506 		for (i = 0; i < numTrays; i++) {
507 			pfs = ppfs[i].form;
508 			if (pfs)
509 				pfs->mounted++;
510 		}
511 	}
512 }
513 
514 /**
515  ** parseFormList()
516  **/
517 
518 static PFSTATUS *
519 parseFormList(char *formList, short *num)
520 {
521 	int i;
522 	FSTATUS *pfs;
523 	PFSTATUS  *ppfs;
524 	short numForms=0;
525 	char *endPtr,*ptr;
526 
527 
528 	ptr = strchr(formList,*LP_SEP);
529 	while (ptr)  {
530 		numForms++;
531 		ptr = strchr(ptr+1,*LP_SEP);
532 	}
533 	if ((numForms == 0) && (*formList))
534 		numForms = 1;
535 
536 	if (numForms &&
537 	    (ppfs = (PFSTATUS *) Calloc(numForms, sizeof(PFSTATUS)))) {
538 		endPtr = strchr(formList,*LP_SEP);
539 		if (!endPtr)
540 			endPtr = formList + strlen(formList);
541 
542 		ptr = formList;
543 		for (i = 0; endPtr && (i < numForms); i++) {
544 			*endPtr = 0;
545 			ppfs[i].form = pfs = search_ftable(ptr);
546 			ppfs[i].isAvailable =
547 				((pfs || (!LP_TRAY_UNMOUNT)) ? 1 : 0);
548 			ptr = endPtr+1;
549 			endPtr = strchr(ptr,*LP_SEP);
550 		}
551 		*num = numForms;
552 	} else {
553 		ppfs = NULL;
554 		*num = 0;
555 	}
556 	return(ppfs);
557 }
558 
559 /**
560  ** dump_pstatus() - DUMP PRINTER STATUS FILE
561  **/
562 
563 void
564 dump_pstatus(void)
565 {
566 	PSTATUS			*ppsend;
567 	int fd;
568 	register PSTATUS	*pps;
569 	register int		f;
570 
571 
572 	if (!pstatus)
573 		pstatus = makepath(Lp_System, PSTATUSFILE, (char *)0);
574 	if ((fd = open_locked(pstatus, "w", MODE_READ)) < 0) {
575 		note ("Can't open file \"%s\" (%s).\n", pstatus, PERROR);
576 		return;
577 	}
578 
579 	for (pps = PStatus, ppsend = &PStatus[PT_Size]; pps < ppsend; pps++)
580 		if (pps->printer->name)
581 			for (f = 0; f < PST_MAX; f++) switch (f) {
582 			case PST_BRK:
583 				(void)fdprintf(fd, "+%s\n", STATUS_BREAK);
584 				break;
585 			case PST_NAME:
586 				(void)fdprintf(fd, "%s\n",
587 					NB(pps->printer->name));
588 				break;
589 			case PST_STATUS:
590 				(void)fdprintf(fd, "%s %s\n",
591 					(pps->status & PS_DISABLED ?
592 					    NAME_DISABLED : NAME_ENABLED),
593 					(pps->status & PS_REJECTED ?
594 					    NAME_REJECTING : NAME_ACCEPTING));
595 				break;
596 			case PST_DATE:
597 				(void)fdprintf(fd, "%ld %ld\n", pps->dis_date,
598 					pps->rej_date);
599 				break;
600 			case PST_DISREAS:
601 				put_multi_line(fd, pps->dis_reason);
602 				break;
603 			case PST_REJREAS:
604 				put_multi_line(fd, pps->rej_reason);
605 				break;
606 			case PST_PWHEEL:
607 				(void)fdprintf(fd, "%s\n",
608 					NB(pps->pwheel_name));
609 				break;
610 			case PST_FORM: {
611 				char *list;
612 				list = showForms(pps);
613 				(void)fdprintf(fd, "%s\n", (list ? list : ""));
614 				if (list)
615 					Free(list);
616 				break;
617 				}
618 			}
619 
620 	close(fd);
621 
622 	return;
623 }
624 
625 /**
626  ** dump_fault_status() - DUMP PRINTER FAULT STATUS FILE
627  **/
628 
629 void
630 dump_fault_status(PSTATUS *pps)
631 {
632 	int fd;
633 	char		*fault_status, *printerName;
634 
635 	printerName = pps->printer->name;
636 	fault_status = makepath(Lp_A_Printers, printerName, FAULT_MESSAGE_FILE,
637 			(char *) 0);
638 	if ((fd = open_locked(fault_status, "w", MODE_READ)) < 0) {
639 		syslog(LOG_DEBUG, "Can't open file %s (%m)\n", fault_status);
640 	} else {
641 		fdprintf(fd, "%s\n", pps->fault_reason);
642 		close(fd);
643 	}
644 
645 	Free(fault_status);
646 	return;
647 }
648 
649 
650 /**
651  ** dump_cstatus() - DUMP CLASS STATUS FILE
652  **/
653 
654 void
655 dump_cstatus(void)
656 {
657 	CSTATUS			*pcsend;
658 	int fd;
659 	register CSTATUS	*pcs;
660 	register int		f;
661 
662 
663 	if (!cstatus)
664 		cstatus = makepath(Lp_System, CSTATUSFILE, (char *)0);
665 	if ((fd = open_locked(cstatus, "w", MODE_READ)) < 0) {
666 		syslog(LOG_DEBUG, "Can't open file %s (%m)\n", cstatus);
667 		return;
668 	}
669 
670 	for (pcs = CStatus, pcsend = &CStatus[CT_Size]; pcs < pcsend; pcs++)
671 		if (pcs->class->name)
672 			for (f = 0; f < CST_MAX; f++) switch (f) {
673 			case CST_BRK:
674 				(void)fdprintf(fd, "%s\n", STATUS_BREAK);
675 				break;
676 			case CST_NAME:
677 				(void)fdprintf(fd, "%s\n",
678 					NB(pcs->class->name));
679 				break;
680 			case CST_STATUS:
681 				(void)fdprintf(fd, "%s\n",
682 					(pcs->status & CS_REJECTED ?
683 					    NAME_REJECTING : NAME_ACCEPTING)
684 				);
685 				break;
686 			case CST_DATE:
687 				(void)fdprintf(fd, "%ld\n", pcs->rej_date);
688 				break;
689 			case CST_REJREAS:
690 				put_multi_line(fd, pcs->rej_reason);
691 				break;
692 			}
693 
694 	close(fd);
695 
696 	return;
697 }
698 
699 /**
700  ** put_multi_line() - PRINT OUT MULTI-LINE TEXT
701  **/
702 
703 static void
704 put_multi_line(int fd, char *buf)
705 {
706 	register char		*cp,
707 				*p;
708 
709 	if (!buf) {
710 		(void)fdprintf(fd, "\n");
711 		return;
712 	}
713 
714 	for (p = buf; (cp = strchr(p, '\n')); ) {
715 		*cp++ = 0;
716 		(void)fdprintf(fd, "%s\\\n", p);
717 		p = cp;
718 	}
719 	(void)fdprintf(fd, "%s\n", p);
720 	return;
721 }
722