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