1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs 
22355b4669Sjacobs /*
23*4da0bd73SKeerthi Kondaka  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24355b4669Sjacobs  */
25355b4669Sjacobs 
26355b4669Sjacobs /* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */
27355b4669Sjacobs 
28355b4669Sjacobs #include <stdio.h>
29355b4669Sjacobs #include <stdlib.h>
30355b4669Sjacobs #include <unistd.h>
31355b4669Sjacobs #include <sys/types.h>
32355b4669Sjacobs #include <sys/stat.h>
33355b4669Sjacobs #include <sys/fcntl.h>
34355b4669Sjacobs #include <time.h>
35355b4669Sjacobs #include <ctype.h>
36355b4669Sjacobs #include <string.h>
37355b4669Sjacobs #include <stdarg.h>
3851208d12Sjacobs #include <regex.h>
39355b4669Sjacobs 
40355b4669Sjacobs #include <papi_impl.h>
41355b4669Sjacobs 
4251208d12Sjacobs /* The string is modified by this call */
4351208d12Sjacobs static char *
regvalue(regmatch_t match,char * string)4451208d12Sjacobs regvalue(regmatch_t match, char *string)
4551208d12Sjacobs {
4651208d12Sjacobs 	char *result = NULL;
4751208d12Sjacobs 
4851208d12Sjacobs 	if (match.rm_so != match.rm_eo) {
4951208d12Sjacobs 		result = string + match.rm_so;
5051208d12Sjacobs 		*(result + (match.rm_eo - match.rm_so)) = '\0';
5151208d12Sjacobs 	}
5251208d12Sjacobs 
5351208d12Sjacobs 	return (result);
5451208d12Sjacobs }
5551208d12Sjacobs 
5651208d12Sjacobs /*
5751208d12Sjacobs  * Print job entries start with:
5851208d12Sjacobs  * 	(user):	(rank)			[job (number) (...)]
5951208d12Sjacobs  *   (user) is the job-owner's user name
6051208d12Sjacobs  *   (rank) is the rank in queue. (active, 1st, 2nd, ...)
6151208d12Sjacobs  *   (number) is the job number
6251208d12Sjacobs  *   (...) is an optional hostname
6351208d12Sjacobs  *   some servers will use whitespace a little differently than is displayed
6451208d12Sjacobs  *   above.  The regular expression below makes whitespace optional in some
6551208d12Sjacobs  *   places.
6651208d12Sjacobs  */
67356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *job_expr = "^(.*[[:alnum:]]):[[:space:]]+([[:alnum:]]+)"\
68356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"[[:space:]]+[[][[:space:]]*job[[:space:]]*([[:digit:]]+)"\
69356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"[[:space:]]*(.*)]";
7051208d12Sjacobs static regex_t job_re;
7151208d12Sjacobs 
72cf73e6abSsonam gupta - Sun Microsystems - Bangalore India /*
73cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  * Print job entries for remote windows printer start with:
74cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *	Owner Status Jobname Job-Id Size Pages Priority
75cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    e.g:
76cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Owner   Status        Jobname      Job-Id  Size  Pages Priority
77cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    ------------------------------------------------------------
78cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    root (10.3. Waiting   /etc/release  2	 240   1     4
79cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *
80cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Owner is the job-owner's user name
81cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Status is the job-status (printing, waiting, error)
82cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Jobname is the name of the job to be printed
83cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Job-Id is the id of the job queued to be printed
84cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Size is the size of the job in bytes
85cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Pages is the number of pages of the job
86cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *    Priority is the job-priority
87cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  */
88356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *wjob_expr = "^([[:alnum:]]+)[[:space:]]*[(](.*)[)]*[[:space:]]"\
89356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"+([[:alnum:]]+)[[:space:]]+(.*)([[:alnum:]]+)(.*)[[:space:]]+"\
90356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)"\
91356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"[[:space:]]+([[:digit:]]+)";
92cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static regex_t wjob_re;
93cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
94cf73e6abSsonam gupta - Sun Microsystems - Bangalore India /*
95cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  * Windows job header is in the following format
96cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  * Owner  Status    Jobname      Job-Id    Size   Pages  Priority
97cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  * --------------------------------------------------------------
98cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  */
99356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *whjob_expr = "Owner       Status         Jobname          Job-Id"\
100356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"    Size   Pages  Priority";
101cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static regex_t whjob_re;
102cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
103cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static char *wline_expr = "----------";
104cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static regex_t wline_re;
105cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
10651208d12Sjacobs /*
10751208d12Sjacobs  * status line(s) for "processing" printers will contain one of the following:
10851208d12Sjacobs  *	ready and printing
10951208d12Sjacobs  *	Printing
110356a8421Ssonam gupta - Sun Microsystems - Bangalore India  *	processing
11151208d12Sjacobs  */
112356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *proc_expr = "(ready and printing|printing|processing)";
11351208d12Sjacobs static regex_t proc_re;
11451208d12Sjacobs 
11551208d12Sjacobs /*
11651208d12Sjacobs  * status line(s) for "idle" printers will contain one of the following:
11751208d12Sjacobs  *	no entries
11851208d12Sjacobs  *	(printer) is ready
11951208d12Sjacobs  *	idle
12051208d12Sjacobs  */
12151208d12Sjacobs static char *idle_expr = "(no entries|is ready| idle)";
12251208d12Sjacobs static regex_t idle_re;
12351208d12Sjacobs 
124cf73e6abSsonam gupta - Sun Microsystems - Bangalore India /*
125356a8421Ssonam gupta - Sun Microsystems - Bangalore India  * Printer state reason (For Windows remote printers)
126cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  *	Paused
127cf73e6abSsonam gupta - Sun Microsystems - Bangalore India  */
128cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static char *state_reason_expr = "(Paused)";
129cf73e6abSsonam gupta - Sun Microsystems - Bangalore India static regex_t state_reason_re;
130cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
13151208d12Sjacobs /*
13251208d12Sjacobs  * document line(s)
13351208d12Sjacobs  *	(copies) copies of (name)		(size) bytes
13451208d12Sjacobs  *	(name)		(size) bytes
13551208d12Sjacobs  *   document lines can be in either format above.
13651208d12Sjacobs  *   (copies) is the number of copies of the document to print
13751208d12Sjacobs  *   (name) is the name of the document: /etc/motd, ...
13851208d12Sjacobs  *   (size) is the number of bytes in the document data
13951208d12Sjacobs  */
140356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *doc1_expr = "[[:space:]]+(([[:digit:]]+) copies of )"\
141356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes";
142356a8421Ssonam gupta - Sun Microsystems - Bangalore India static char *doc2_expr = "[[:space:]]+()([^[:space:]]+)[[:space:]]*"\
143356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	"([[:digit:]]+) bytes";
14451208d12Sjacobs static regex_t doc1_re;
14551208d12Sjacobs static regex_t doc2_re;
14651208d12Sjacobs 
147356a8421Ssonam gupta - Sun Microsystems - Bangalore India /* Printer-state for Windows */
148356a8421Ssonam gupta - Sun Microsystems - Bangalore India static int win_state = 0x03; /* Idle */
149356a8421Ssonam gupta - Sun Microsystems - Bangalore India 
150355b4669Sjacobs static void
parse_lpd_job(service_t * svc,job_t ** job,int fd,char * line,int len)15151208d12Sjacobs parse_lpd_job(service_t *svc, job_t **job, int fd, char *line, int len)
152355b4669Sjacobs {
153355b4669Sjacobs 	papi_attribute_t **attributes = NULL;
154cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	regmatch_t matches[10];
15551208d12Sjacobs 	char *s;
156355b4669Sjacobs 	int octets = 0;
157cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	int flag = 0;
158355b4669Sjacobs 
159cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	/*
160cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 * job_re and wjob_re were compiled in the calling function
161cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 * first check for solaris jobs
162cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 * if there is no-match check for windows jobs
163cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 */
16451208d12Sjacobs 
165cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	if (regexec(&job_re, line, (size_t)5, matches, 0) == REG_NOMATCH) {
166cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if (regexec(&wjob_re, line, (size_t)10, matches, 0)
167cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    == REG_NOMATCH)
168cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			return;
169cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		else
170cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			flag = 1;
171cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	}
172355b4669Sjacobs 
173cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	if (flag == 1) {
174cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		/* Windows job */
175cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		/* first match is job-id */
176356a8421Ssonam gupta - Sun Microsystems - Bangalore India 
177cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[1], line)) == NULL)
178cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "nobody";
179cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
180cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-originating-user-name", s);
18151208d12Sjacobs 
182cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[4], line)) == NULL)
183cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "unknown";
184cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
185cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-name", s);
186cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
187cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-file-names", s);
18851208d12Sjacobs 
189cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[7], line)) == NULL)
190cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "0";
191cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
192cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-id", atoi(s));
193cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
194cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[8], line)) == NULL)
195cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "0";
196cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		octets = atoi(s);
197cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes,
198cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    PAPI_ATTR_APPEND, "job-file-sizes", atoi(s));
199cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
200356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		/*
201356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * Since a job has been found so the printer state is either
202356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * 'stopped' or 'processing'
203356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * By default it is "processing"
204356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 */
205356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		win_state = 0x04;
206cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	} else {
207cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		/* Solaris job */
208cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[1], line)) == NULL)
209cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "nobody";
210cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
211cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-originating-user-name", s);
212cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
213cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[2], line)) == NULL)
214cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "0";
215cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
216cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "number-of-intervening-jobs", atoi(s) - 1);
217cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
218cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[3], line)) == NULL)
219cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = "0";
220cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
221cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-id", atoi(s));
222cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
223cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((s = regvalue(matches[4], line)) == NULL)
224cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			s = svc->uri->host;
225cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
226cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "job-originating-host-name", s);
227cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	}
228355b4669Sjacobs 
22951208d12Sjacobs 	while ((fdgets(line, len, fd) != NULL) &&
230cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) &&
231cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) {
23251208d12Sjacobs 		int size = 0, copies = 1;
23351208d12Sjacobs 		/* process copies/documents */
23451208d12Sjacobs 
23551208d12Sjacobs 		/* doc1_re and doc2_re were compiled in the calling function */
23651208d12Sjacobs 		if ((regexec(&doc1_re, line, (size_t)4, matches, 0) != 0) &&
23751208d12Sjacobs 		    (regexec(&doc2_re, line, (size_t)4, matches, 0) != 0))
23851208d12Sjacobs 			continue;
23951208d12Sjacobs 
24051208d12Sjacobs 		if ((s = regvalue(matches[1], line)) == NULL)
24151208d12Sjacobs 			s = "1";
24251208d12Sjacobs 		if ((copies = atoi(s)) < 1)
243355b4669Sjacobs 			copies = 1;
24451208d12Sjacobs 
24551208d12Sjacobs 		if ((s = regvalue(matches[2], line)) == NULL)
24651208d12Sjacobs 			s = "unknown";
24751208d12Sjacobs 		papiAttributeListAddString(&attributes,
248cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    PAPI_ATTR_APPEND, "job-name", s);
24951208d12Sjacobs 		papiAttributeListAddString(&attributes,
250cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    PAPI_ATTR_APPEND, "job-file-names", s);
25151208d12Sjacobs 
25251208d12Sjacobs 		if ((s = regvalue(matches[3], line)) == NULL)
25351208d12Sjacobs 			s = "0";
25451208d12Sjacobs 		size = atoi(s);
255cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
25651208d12Sjacobs 		papiAttributeListAddInteger(&attributes,
257cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    PAPI_ATTR_APPEND, "job-file-sizes", size);
258355b4669Sjacobs 
25951208d12Sjacobs 		octets += (size * copies);
260355b4669Sjacobs 	}
261355b4669Sjacobs 
262355b4669Sjacobs 	papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND,
263cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    "job-k-octets", octets/1024);
264355b4669Sjacobs 	papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND,
265cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    "job-octets", octets);
266355b4669Sjacobs 	papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
267cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    "printer-name", queue_name_from_uri(svc->uri));
268355b4669Sjacobs 
269355b4669Sjacobs 	if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL)
270355b4669Sjacobs 		(*job)->attributes = attributes;
271355b4669Sjacobs }
272355b4669Sjacobs 
273355b4669Sjacobs void
parse_lpd_query(service_t * svc,int fd)274355b4669Sjacobs parse_lpd_query(service_t *svc, int fd)
275355b4669Sjacobs {
276355b4669Sjacobs 	papi_attribute_t **attributes = NULL;
277355b4669Sjacobs 	cache_t *cache = NULL;
278355b4669Sjacobs 	int state = 0x03; /* idle */
279355b4669Sjacobs 	char line[128];
28051208d12Sjacobs 	char status[1024];
28151208d12Sjacobs 	char *s;
282356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	int win_flag = 0;
283355b4669Sjacobs 
284355b4669Sjacobs 	papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
285cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    "printer-name", queue_name_from_uri(svc->uri));
286355b4669Sjacobs 
28751208d12Sjacobs 	if (uri_to_string(svc->uri, status, sizeof (status)) == 0)
288355b4669Sjacobs 		papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
289cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    "printer-uri-supported", status);
29051208d12Sjacobs 
29151208d12Sjacobs 	/*
29251208d12Sjacobs 	 * on most systems, status is a single line, but some appear to
29351208d12Sjacobs 	 * return multi-line status messages.  To get the "best" possible
29451208d12Sjacobs 	 * printer-state-reason, we accumulate the text until we hit the
29551208d12Sjacobs 	 * first print job entry.
29651208d12Sjacobs 	 *
29751208d12Sjacobs 	 * Print job entries start with:
29851208d12Sjacobs 	 * 	user:	rank			[job number ...]
29951208d12Sjacobs 	 */
30051208d12Sjacobs 	(void) regcomp(&job_re, job_expr, REG_EXTENDED|REG_ICASE);
30151208d12Sjacobs 
302cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	/*
303cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 * For remote windows printers
304cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 * Print job entries start with:
305cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 *  Owner  Status  Jobname  Job-Id  Size  Pages  Priority
306cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	 */
307cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	(void) regcomp(&wjob_re, wjob_expr, REG_EXTENDED|REG_ICASE);
308cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	(void) regcomp(&whjob_re, whjob_expr, REG_EXTENDED|REG_ICASE);
309cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	(void) regcomp(&wline_re, wline_expr, REG_EXTENDED|REG_ICASE);
310cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
31151208d12Sjacobs 	status[0] = '\0';
312cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
31351208d12Sjacobs 	while ((fdgets(line, sizeof (line), fd) != NULL) &&
314cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) &&
315cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) {
316cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		/*
317cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		 * When windows job queue gets queried following header
318cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		 * should not get printed
319cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		 * Owner Status Jobname Job-Id Size Pages Priority
320cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		 * -----------------------------------------------
321cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		 */
322cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		if ((regexec(&whjob_re, line, (size_t)0, NULL, 0)
323356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		    == REG_NOMATCH) &&
324356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		    (regexec(&wline_re, line, (size_t)0, NULL, 0)
325cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 		    == REG_NOMATCH))
326cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			strlcat(status, line, sizeof (status));
32751208d12Sjacobs 	}
328cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
32951208d12Sjacobs 	/* chop off trailing whitespace */
33051208d12Sjacobs 	s = status + strlen(status) - 1;
33151208d12Sjacobs 	while ((s > status) && (isspace(*s) != 0))
33251208d12Sjacobs 		*s-- = '\0';
333355b4669Sjacobs 
334355b4669Sjacobs 	papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
335cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    "printer-state-reasons", status);
336355b4669Sjacobs 
337356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	/* Check if this is for Windows remote printers */
338356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	if (strstr(status, "Windows")) {
339356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		/*
340356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * It is a remote windows printer
341356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * By default set the status as idle
342356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 * Set the printer-state after call to "parse_lpd_job"
343356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		 */
344356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		win_flag = 1;
345356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		(void) regcomp(&state_reason_re, state_reason_expr,
346356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		    REG_EXTENDED|REG_ICASE);
347cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 
348356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		if (regexec(&state_reason_re, status, (size_t)0, NULL, 0) == 0)
349356a8421Ssonam gupta - Sun Microsystems - Bangalore India 			state = 0x05; /* stopped */
350356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	} else {
351356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		(void) regcomp(&proc_re, proc_expr, REG_EXTENDED|REG_ICASE);
352356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		(void) regcomp(&idle_re, idle_expr, REG_EXTENDED|REG_ICASE);
353355b4669Sjacobs 
354356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		if (regexec(&proc_re, status, (size_t)0, NULL, 0) == 0)
355356a8421Ssonam gupta - Sun Microsystems - Bangalore India 			state = 0x04; /* processing */
356356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		else if (regexec(&idle_re, status, (size_t)0, NULL, 0) == 0)
357356a8421Ssonam gupta - Sun Microsystems - Bangalore India 			state = 0x03; /* idle */
358356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		else
359356a8421Ssonam gupta - Sun Microsystems - Bangalore India 			state = 0x05; /* stopped */
360356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
361356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		    "printer-state", state);
362356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	}
363355b4669Sjacobs 
364355b4669Sjacobs 	if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL)
365355b4669Sjacobs 		return;
366355b4669Sjacobs 
367355b4669Sjacobs 	if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer)))
368cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 	    == NULL)
369355b4669Sjacobs 		return;
370355b4669Sjacobs 
371355b4669Sjacobs 	cache->printer->attributes = attributes;
372355b4669Sjacobs 	svc->cache = cache;
373355b4669Sjacobs 
37451208d12Sjacobs 	(void) regcomp(&doc1_re, doc1_expr, REG_EXTENDED|REG_ICASE);
37551208d12Sjacobs 	(void) regcomp(&doc2_re, doc2_expr, REG_EXTENDED|REG_ICASE);
37651208d12Sjacobs 	/* process job related entries */
37751208d12Sjacobs 	while (line[0] != '\0') {
37851208d12Sjacobs 		job_t *job = NULL;
37951208d12Sjacobs 
38051208d12Sjacobs 		parse_lpd_job(svc, &job, fd, line, sizeof (line));
38151208d12Sjacobs 		if (job == NULL)
38251208d12Sjacobs 			break;
38351208d12Sjacobs 		list_append(&cache->jobs, job);
384355b4669Sjacobs 	}
385355b4669Sjacobs 
386356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	/*
387356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	 * For remote windows printer set the printer-state
388356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	 * after parse_lpd_job
389356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	 */
390356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	if (win_flag) {
391356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		if (state == 0x05)
392356a8421Ssonam gupta - Sun Microsystems - Bangalore India 			win_state = state;
393356a8421Ssonam gupta - Sun Microsystems - Bangalore India 
394356a8421Ssonam gupta - Sun Microsystems - Bangalore India 		papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
395356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	    "printer-state", win_state);
396356a8421Ssonam gupta - Sun Microsystems - Bangalore India 	}
397355b4669Sjacobs 	time(&cache->timestamp);
398355b4669Sjacobs }
399355b4669Sjacobs 
400355b4669Sjacobs void
cache_update(service_t * svc)401355b4669Sjacobs cache_update(service_t *svc)
402355b4669Sjacobs {
403355b4669Sjacobs 	int fd;
404355b4669Sjacobs 
405355b4669Sjacobs 	if (svc == NULL)
406355b4669Sjacobs 		return;
407355b4669Sjacobs 
408*4da0bd73SKeerthi Kondaka 	if (svc->cache != NULL)	{ /* this should be time based */
409*4da0bd73SKeerthi Kondaka 		if (svc->cache->jobs == NULL) {
410*4da0bd73SKeerthi Kondaka 			free(svc->cache);
411*4da0bd73SKeerthi Kondaka 			svc->cache = NULL;
412*4da0bd73SKeerthi Kondaka 		} else
413*4da0bd73SKeerthi Kondaka 			return;
414*4da0bd73SKeerthi Kondaka 	}
415*4da0bd73SKeerthi Kondaka 
4164bd2082fSceastha 	if ((fd = lpd_open(svc, 'q', NULL, 15)) < 0)
417355b4669Sjacobs 		return;
418355b4669Sjacobs 
419355b4669Sjacobs 	parse_lpd_query(svc, fd);
420355b4669Sjacobs 
421355b4669Sjacobs 	close(fd);
422355b4669Sjacobs }
423355b4669Sjacobs 
424355b4669Sjacobs papi_status_t
lpd_find_printer_info(service_t * svc,printer_t ** printer)425355b4669Sjacobs lpd_find_printer_info(service_t *svc, printer_t **printer)
426355b4669Sjacobs {
427355b4669Sjacobs 	papi_status_t result = PAPI_BAD_ARGUMENT;
428355b4669Sjacobs 
429355b4669Sjacobs 	if ((svc == NULL) || (printer == NULL))
430355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
431355b4669Sjacobs 
432355b4669Sjacobs 	cache_update(svc);
433355b4669Sjacobs 
434355b4669Sjacobs 	if (svc->cache != NULL) {
435355b4669Sjacobs 		*printer = svc->cache->printer;
436355b4669Sjacobs 		result = PAPI_OK;
437355b4669Sjacobs 	} else
438355b4669Sjacobs 		result = PAPI_NOT_FOUND;
439355b4669Sjacobs 
440355b4669Sjacobs 	return (result);
441355b4669Sjacobs }
442355b4669Sjacobs 
443355b4669Sjacobs papi_status_t
lpd_find_jobs_info(service_t * svc,job_t *** jobs)444355b4669Sjacobs lpd_find_jobs_info(service_t *svc, job_t ***jobs)
445355b4669Sjacobs {
446355b4669Sjacobs 	papi_status_t result = PAPI_BAD_ARGUMENT;
447355b4669Sjacobs 
448355b4669Sjacobs 	if (svc != NULL) {
449355b4669Sjacobs 		cache_update(svc);
450355b4669Sjacobs 
451355b4669Sjacobs 		if (svc->cache != NULL) {
452355b4669Sjacobs 			*jobs = svc->cache->jobs;
453355b4669Sjacobs 			result = PAPI_OK;
454355b4669Sjacobs 		}
455355b4669Sjacobs 	}
456355b4669Sjacobs 
457*4da0bd73SKeerthi Kondaka 	/*
458*4da0bd73SKeerthi Kondaka 	 * cache jobs is free()-ed in
459*4da0bd73SKeerthi Kondaka 	 * libpapi-dynamic/common/printer.c -
460*4da0bd73SKeerthi Kondaka 	 * papiPrinterListJobs() cache printer is
461*4da0bd73SKeerthi Kondaka 	 * free()-ed by the caller of
462*4da0bd73SKeerthi Kondaka 	 * lpd_find_printer_info Invalidate the
463*4da0bd73SKeerthi Kondaka 	 * cache by freeing the cache.
464*4da0bd73SKeerthi Kondaka 	 */
465*4da0bd73SKeerthi Kondaka 	free(svc->cache);
466*4da0bd73SKeerthi Kondaka 	svc->cache = NULL;
467*4da0bd73SKeerthi Kondaka 
468355b4669Sjacobs 	return (result);
469355b4669Sjacobs }
470355b4669Sjacobs 
471355b4669Sjacobs papi_status_t
lpd_find_job_info(service_t * svc,int job_id,job_t ** job)472355b4669Sjacobs lpd_find_job_info(service_t *svc, int job_id, job_t **job)
473355b4669Sjacobs {
474355b4669Sjacobs 	papi_status_t result = PAPI_BAD_ARGUMENT;
475355b4669Sjacobs 	job_t **jobs;
476355b4669Sjacobs 
477*4da0bd73SKeerthi Kondaka 	if ((lpd_find_jobs_info(svc, &jobs) == PAPI_OK) && (jobs != NULL)) {
478355b4669Sjacobs 		int i;
479355b4669Sjacobs 
480355b4669Sjacobs 		*job = NULL;
481355b4669Sjacobs 		for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) {
482355b4669Sjacobs 			int id = -1;
483355b4669Sjacobs 
484355b4669Sjacobs 			papiAttributeListGetInteger(jobs[i]->attributes, NULL,
485cf73e6abSsonam gupta - Sun Microsystems - Bangalore India 			    "job-id", &id);
486355b4669Sjacobs 			if (id == job_id)
487355b4669Sjacobs 				*job = jobs[i];
488355b4669Sjacobs 		}
489355b4669Sjacobs 
490355b4669Sjacobs 		if (*job != NULL)
491355b4669Sjacobs 			result = PAPI_OK;
492355b4669Sjacobs 	}
493355b4669Sjacobs 
494355b4669Sjacobs 	return (result);
495355b4669Sjacobs }
496355b4669Sjacobs 
497355b4669Sjacobs void
cache_free(cache_t * item)498355b4669Sjacobs cache_free(cache_t *item)
499355b4669Sjacobs {
500355b4669Sjacobs 	if (item != NULL) {
501355b4669Sjacobs 		if (item->printer != NULL)
502355b4669Sjacobs 			papiPrinterFree((papi_printer_t *)item->printer);
503355b4669Sjacobs 		if (item->jobs != NULL)
504355b4669Sjacobs 			papiJobListFree((papi_job_t *)item->jobs);
505355b4669Sjacobs 		free(item);
506355b4669Sjacobs 	}
507355b4669Sjacobs }
508