Home | History | Annotate | Download | only in lpsched
      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