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