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