12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 238533SSonam.Gupta@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282264Sjacobs /* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */ 292264Sjacobs 302264Sjacobs #include <stdio.h> 312264Sjacobs #include <stdlib.h> 322264Sjacobs #include <unistd.h> 332264Sjacobs #include <sys/types.h> 342264Sjacobs #include <sys/stat.h> 352264Sjacobs #include <sys/fcntl.h> 362264Sjacobs #include <time.h> 372264Sjacobs #include <ctype.h> 382264Sjacobs #include <string.h> 392264Sjacobs #include <stdarg.h> 403758Sjacobs #include <regex.h> 412264Sjacobs 422264Sjacobs #include <papi_impl.h> 432264Sjacobs 443758Sjacobs /* The string is modified by this call */ 453758Sjacobs static char * 463758Sjacobs regvalue(regmatch_t match, char *string) 472264Sjacobs { 483758Sjacobs char *result = NULL; 493758Sjacobs 503758Sjacobs if (match.rm_so != match.rm_eo) { 513758Sjacobs result = string + match.rm_so; 523758Sjacobs *(result + (match.rm_eo - match.rm_so)) = '\0'; 533758Sjacobs } 543758Sjacobs 553758Sjacobs return (result); 563758Sjacobs } 573758Sjacobs 583758Sjacobs /* 593758Sjacobs * Print job entries start with: 603758Sjacobs * (user): (rank) [job (number) (...)] 613758Sjacobs * (user) is the job-owner's user name 623758Sjacobs * (rank) is the rank in queue. (active, 1st, 2nd, ...) 633758Sjacobs * (number) is the job number 643758Sjacobs * (...) is an optional hostname 653758Sjacobs * some servers will use whitespace a little differently than is displayed 663758Sjacobs * above. The regular expression below makes whitespace optional in some 673758Sjacobs * places. 683758Sjacobs */ 69*9206SSonam.Gupta@Sun.COM static char *job_expr = "^(.*[[:alnum:]]):[[:space:]]+([[:alnum:]]+)"\ 70*9206SSonam.Gupta@Sun.COM "[[:space:]]+[[][[:space:]]*job[[:space:]]*([[:digit:]]+)"\ 71*9206SSonam.Gupta@Sun.COM "[[:space:]]*(.*)]"; 723758Sjacobs static regex_t job_re; 733758Sjacobs 743758Sjacobs /* 758533SSonam.Gupta@Sun.COM * Print job entries for remote windows printer start with: 768533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 778533SSonam.Gupta@Sun.COM * e.g: 788533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 798533SSonam.Gupta@Sun.COM * ------------------------------------------------------------ 808533SSonam.Gupta@Sun.COM * root (10.3. Waiting /etc/release 2 240 1 4 818533SSonam.Gupta@Sun.COM * 828533SSonam.Gupta@Sun.COM * Owner is the job-owner's user name 838533SSonam.Gupta@Sun.COM * Status is the job-status (printing, waiting, error) 848533SSonam.Gupta@Sun.COM * Jobname is the name of the job to be printed 858533SSonam.Gupta@Sun.COM * Job-Id is the id of the job queued to be printed 868533SSonam.Gupta@Sun.COM * Size is the size of the job in bytes 878533SSonam.Gupta@Sun.COM * Pages is the number of pages of the job 888533SSonam.Gupta@Sun.COM * Priority is the job-priority 898533SSonam.Gupta@Sun.COM */ 90*9206SSonam.Gupta@Sun.COM static char *wjob_expr = "^([[:alnum:]]+)[[:space:]]*[(](.*)[)]*[[:space:]]"\ 91*9206SSonam.Gupta@Sun.COM "+([[:alnum:]]+)[[:space:]]+(.*)([[:alnum:]]+)(.*)[[:space:]]+"\ 92*9206SSonam.Gupta@Sun.COM "([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)"\ 93*9206SSonam.Gupta@Sun.COM "[[:space:]]+([[:digit:]]+)"; 948533SSonam.Gupta@Sun.COM static regex_t wjob_re; 958533SSonam.Gupta@Sun.COM 968533SSonam.Gupta@Sun.COM /* 978533SSonam.Gupta@Sun.COM * Windows job header is in the following format 988533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 998533SSonam.Gupta@Sun.COM * -------------------------------------------------------------- 1008533SSonam.Gupta@Sun.COM */ 101*9206SSonam.Gupta@Sun.COM static char *whjob_expr = "Owner Status Jobname Job-Id"\ 102*9206SSonam.Gupta@Sun.COM " Size Pages Priority"; 1038533SSonam.Gupta@Sun.COM static regex_t whjob_re; 1048533SSonam.Gupta@Sun.COM 1058533SSonam.Gupta@Sun.COM static char *wline_expr = "----------"; 1068533SSonam.Gupta@Sun.COM static regex_t wline_re; 1078533SSonam.Gupta@Sun.COM 1088533SSonam.Gupta@Sun.COM /* 1093758Sjacobs * status line(s) for "processing" printers will contain one of the following: 1103758Sjacobs * ready and printing 1113758Sjacobs * Printing 112*9206SSonam.Gupta@Sun.COM * processing 1133758Sjacobs */ 114*9206SSonam.Gupta@Sun.COM static char *proc_expr = "(ready and printing|printing|processing)"; 1153758Sjacobs static regex_t proc_re; 1163758Sjacobs 1173758Sjacobs /* 1183758Sjacobs * status line(s) for "idle" printers will contain one of the following: 1193758Sjacobs * no entries 1203758Sjacobs * (printer) is ready 1213758Sjacobs * idle 1223758Sjacobs */ 1233758Sjacobs static char *idle_expr = "(no entries|is ready| idle)"; 1243758Sjacobs static regex_t idle_re; 1253758Sjacobs 1263758Sjacobs /* 127*9206SSonam.Gupta@Sun.COM * Printer state reason (For Windows remote printers) 1288533SSonam.Gupta@Sun.COM * Paused 1298533SSonam.Gupta@Sun.COM */ 1308533SSonam.Gupta@Sun.COM static char *state_reason_expr = "(Paused)"; 1318533SSonam.Gupta@Sun.COM static regex_t state_reason_re; 1328533SSonam.Gupta@Sun.COM 1338533SSonam.Gupta@Sun.COM /* 1343758Sjacobs * document line(s) 1353758Sjacobs * (copies) copies of (name) (size) bytes 1363758Sjacobs * (name) (size) bytes 1373758Sjacobs * document lines can be in either format above. 1383758Sjacobs * (copies) is the number of copies of the document to print 1393758Sjacobs * (name) is the name of the document: /etc/motd, ... 1403758Sjacobs * (size) is the number of bytes in the document data 1413758Sjacobs */ 142*9206SSonam.Gupta@Sun.COM static char *doc1_expr = "[[:space:]]+(([[:digit:]]+) copies of )"\ 143*9206SSonam.Gupta@Sun.COM "([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes"; 144*9206SSonam.Gupta@Sun.COM static char *doc2_expr = "[[:space:]]+()([^[:space:]]+)[[:space:]]*"\ 145*9206SSonam.Gupta@Sun.COM "([[:digit:]]+) bytes"; 1463758Sjacobs static regex_t doc1_re; 1473758Sjacobs static regex_t doc2_re; 1483758Sjacobs 149*9206SSonam.Gupta@Sun.COM /* Printer-state for Windows */ 150*9206SSonam.Gupta@Sun.COM static int win_state = 0x03; /* Idle */ 151*9206SSonam.Gupta@Sun.COM 1523758Sjacobs static void 1533758Sjacobs parse_lpd_job(service_t *svc, job_t **job, int fd, char *line, int len) 1543758Sjacobs { 1552264Sjacobs papi_attribute_t **attributes = NULL; 1568533SSonam.Gupta@Sun.COM regmatch_t matches[10]; 1573758Sjacobs char *s; 1582264Sjacobs int octets = 0; 1598533SSonam.Gupta@Sun.COM int flag = 0; 1602264Sjacobs 1618533SSonam.Gupta@Sun.COM /* 1628533SSonam.Gupta@Sun.COM * job_re and wjob_re were compiled in the calling function 1638533SSonam.Gupta@Sun.COM * first check for solaris jobs 1648533SSonam.Gupta@Sun.COM * if there is no-match check for windows jobs 1658533SSonam.Gupta@Sun.COM */ 1663758Sjacobs 1678533SSonam.Gupta@Sun.COM if (regexec(&job_re, line, (size_t)5, matches, 0) == REG_NOMATCH) { 1688533SSonam.Gupta@Sun.COM if (regexec(&wjob_re, line, (size_t)10, matches, 0) 1698533SSonam.Gupta@Sun.COM == REG_NOMATCH) 1708533SSonam.Gupta@Sun.COM return; 1718533SSonam.Gupta@Sun.COM else 1728533SSonam.Gupta@Sun.COM flag = 1; 1738533SSonam.Gupta@Sun.COM } 1748533SSonam.Gupta@Sun.COM 1758533SSonam.Gupta@Sun.COM if (flag == 1) { 1768533SSonam.Gupta@Sun.COM /* Windows job */ 1778533SSonam.Gupta@Sun.COM /* first match is job-id */ 178*9206SSonam.Gupta@Sun.COM 1798533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 1808533SSonam.Gupta@Sun.COM s = "nobody"; 1818533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 1828533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 1838533SSonam.Gupta@Sun.COM 1848533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 1858533SSonam.Gupta@Sun.COM s = "unknown"; 1868533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 1878533SSonam.Gupta@Sun.COM "job-name", s); 1888533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 1898533SSonam.Gupta@Sun.COM "job-file-names", s); 1902264Sjacobs 1918533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[7], line)) == NULL) 1928533SSonam.Gupta@Sun.COM s = "0"; 1938533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 1948533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 1958533SSonam.Gupta@Sun.COM 1968533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[8], line)) == NULL) 1978533SSonam.Gupta@Sun.COM s = "0"; 1988533SSonam.Gupta@Sun.COM octets = atoi(s); 1998533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, 2008533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", atoi(s)); 2013758Sjacobs 202*9206SSonam.Gupta@Sun.COM /* 203*9206SSonam.Gupta@Sun.COM * Since a job has been found so the printer state is either 204*9206SSonam.Gupta@Sun.COM * 'stopped' or 'processing' 205*9206SSonam.Gupta@Sun.COM * By default it is "processing" 206*9206SSonam.Gupta@Sun.COM */ 207*9206SSonam.Gupta@Sun.COM win_state = 0x04; 2088533SSonam.Gupta@Sun.COM } else { 2098533SSonam.Gupta@Sun.COM /* Solaris job */ 2108533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 2118533SSonam.Gupta@Sun.COM s = "nobody"; 2128533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 2138533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 2143758Sjacobs 2158533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[2], line)) == NULL) 2168533SSonam.Gupta@Sun.COM s = "0"; 2178533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 2188533SSonam.Gupta@Sun.COM "number-of-intervening-jobs", atoi(s) - 1); 2198533SSonam.Gupta@Sun.COM 2208533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[3], line)) == NULL) 2218533SSonam.Gupta@Sun.COM s = "0"; 2228533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 2238533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 2248533SSonam.Gupta@Sun.COM 2258533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 2268533SSonam.Gupta@Sun.COM s = svc->uri->host; 2278533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 2288533SSonam.Gupta@Sun.COM "job-originating-host-name", s); 2298533SSonam.Gupta@Sun.COM } 2302264Sjacobs 2313758Sjacobs while ((fdgets(line, len, fd) != NULL) && 2328533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 2338533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 2343758Sjacobs int size = 0, copies = 1; 2353758Sjacobs /* process copies/documents */ 2362264Sjacobs 2373758Sjacobs /* doc1_re and doc2_re were compiled in the calling function */ 2383758Sjacobs if ((regexec(&doc1_re, line, (size_t)4, matches, 0) != 0) && 2393758Sjacobs (regexec(&doc2_re, line, (size_t)4, matches, 0) != 0)) 2403758Sjacobs continue; 2412264Sjacobs 2423758Sjacobs if ((s = regvalue(matches[1], line)) == NULL) 2433758Sjacobs s = "1"; 2443758Sjacobs if ((copies = atoi(s)) < 1) 2453758Sjacobs copies = 1; 2462264Sjacobs 2473758Sjacobs if ((s = regvalue(matches[2], line)) == NULL) 2483758Sjacobs s = "unknown"; 2493758Sjacobs papiAttributeListAddString(&attributes, 2508533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-name", s); 2513758Sjacobs papiAttributeListAddString(&attributes, 2528533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-names", s); 2532264Sjacobs 2543758Sjacobs if ((s = regvalue(matches[3], line)) == NULL) 2553758Sjacobs s = "0"; 2563758Sjacobs size = atoi(s); 2578533SSonam.Gupta@Sun.COM 2583758Sjacobs papiAttributeListAddInteger(&attributes, 2598533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", size); 2602264Sjacobs 2613758Sjacobs octets += (size * copies); 2622264Sjacobs } 2632264Sjacobs 2642264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 2658533SSonam.Gupta@Sun.COM "job-k-octets", octets/1024); 2662264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 2678533SSonam.Gupta@Sun.COM "job-octets", octets); 2682264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2698533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2702264Sjacobs 2712264Sjacobs if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) 2722264Sjacobs (*job)->attributes = attributes; 2732264Sjacobs } 2742264Sjacobs 2752264Sjacobs void 2762264Sjacobs parse_lpd_query(service_t *svc, int fd) 2772264Sjacobs { 2782264Sjacobs papi_attribute_t **attributes = NULL; 2792264Sjacobs cache_t *cache = NULL; 2802264Sjacobs int state = 0x03; /* idle */ 2812264Sjacobs char line[128]; 2823758Sjacobs char status[1024]; 2833758Sjacobs char *s; 284*9206SSonam.Gupta@Sun.COM int win_flag = 0; 2852264Sjacobs 2862264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2878533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2882264Sjacobs 2893758Sjacobs if (uri_to_string(svc->uri, status, sizeof (status)) == 0) 2902264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2918533SSonam.Gupta@Sun.COM "printer-uri-supported", status); 2923758Sjacobs 2933758Sjacobs /* 2943758Sjacobs * on most systems, status is a single line, but some appear to 2953758Sjacobs * return multi-line status messages. To get the "best" possible 2963758Sjacobs * printer-state-reason, we accumulate the text until we hit the 2973758Sjacobs * first print job entry. 2983758Sjacobs * 2993758Sjacobs * Print job entries start with: 3003758Sjacobs * user: rank [job number ...] 3013758Sjacobs */ 3023758Sjacobs (void) regcomp(&job_re, job_expr, REG_EXTENDED|REG_ICASE); 3033758Sjacobs 3048533SSonam.Gupta@Sun.COM /* 3058533SSonam.Gupta@Sun.COM * For remote windows printers 3068533SSonam.Gupta@Sun.COM * Print job entries start with: 3078533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 3088533SSonam.Gupta@Sun.COM */ 3098533SSonam.Gupta@Sun.COM (void) regcomp(&wjob_re, wjob_expr, REG_EXTENDED|REG_ICASE); 3108533SSonam.Gupta@Sun.COM (void) regcomp(&whjob_re, whjob_expr, REG_EXTENDED|REG_ICASE); 3118533SSonam.Gupta@Sun.COM (void) regcomp(&wline_re, wline_expr, REG_EXTENDED|REG_ICASE); 3128533SSonam.Gupta@Sun.COM 3133758Sjacobs status[0] = '\0'; 3148533SSonam.Gupta@Sun.COM 3153758Sjacobs while ((fdgets(line, sizeof (line), fd) != NULL) && 3168533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 3178533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 3188533SSonam.Gupta@Sun.COM /* 3198533SSonam.Gupta@Sun.COM * When windows job queue gets queried following header 3208533SSonam.Gupta@Sun.COM * should not get printed 3218533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 3228533SSonam.Gupta@Sun.COM * ----------------------------------------------- 3238533SSonam.Gupta@Sun.COM */ 3248533SSonam.Gupta@Sun.COM if ((regexec(&whjob_re, line, (size_t)0, NULL, 0) 325*9206SSonam.Gupta@Sun.COM == REG_NOMATCH) && 326*9206SSonam.Gupta@Sun.COM (regexec(&wline_re, line, (size_t)0, NULL, 0) 3278533SSonam.Gupta@Sun.COM == REG_NOMATCH)) 3288533SSonam.Gupta@Sun.COM strlcat(status, line, sizeof (status)); 3293758Sjacobs } 3308533SSonam.Gupta@Sun.COM 3313758Sjacobs /* chop off trailing whitespace */ 3323758Sjacobs s = status + strlen(status) - 1; 3333758Sjacobs while ((s > status) && (isspace(*s) != 0)) 3343758Sjacobs *s-- = '\0'; 3352264Sjacobs 3362264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 3378533SSonam.Gupta@Sun.COM "printer-state-reasons", status); 3382264Sjacobs 339*9206SSonam.Gupta@Sun.COM /* Check if this is for Windows remote printers */ 340*9206SSonam.Gupta@Sun.COM if (strstr(status, "Windows")) { 341*9206SSonam.Gupta@Sun.COM /* 342*9206SSonam.Gupta@Sun.COM * It is a remote windows printer 343*9206SSonam.Gupta@Sun.COM * By default set the status as idle 344*9206SSonam.Gupta@Sun.COM * Set the printer-state after call to "parse_lpd_job" 345*9206SSonam.Gupta@Sun.COM */ 346*9206SSonam.Gupta@Sun.COM win_flag = 1; 347*9206SSonam.Gupta@Sun.COM (void) regcomp(&state_reason_re, state_reason_expr, 348*9206SSonam.Gupta@Sun.COM REG_EXTENDED|REG_ICASE); 3498533SSonam.Gupta@Sun.COM 350*9206SSonam.Gupta@Sun.COM if (regexec(&state_reason_re, status, (size_t)0, NULL, 0) == 0) 351*9206SSonam.Gupta@Sun.COM state = 0x05; /* stopped */ 352*9206SSonam.Gupta@Sun.COM } else { 353*9206SSonam.Gupta@Sun.COM (void) regcomp(&proc_re, proc_expr, REG_EXTENDED|REG_ICASE); 354*9206SSonam.Gupta@Sun.COM (void) regcomp(&idle_re, idle_expr, REG_EXTENDED|REG_ICASE); 3552264Sjacobs 356*9206SSonam.Gupta@Sun.COM if (regexec(&proc_re, status, (size_t)0, NULL, 0) == 0) 357*9206SSonam.Gupta@Sun.COM state = 0x04; /* processing */ 358*9206SSonam.Gupta@Sun.COM else if (regexec(&idle_re, status, (size_t)0, NULL, 0) == 0) 359*9206SSonam.Gupta@Sun.COM state = 0x03; /* idle */ 360*9206SSonam.Gupta@Sun.COM else 361*9206SSonam.Gupta@Sun.COM state = 0x05; /* stopped */ 362*9206SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 363*9206SSonam.Gupta@Sun.COM "printer-state", state); 364*9206SSonam.Gupta@Sun.COM } 3652264Sjacobs 3662264Sjacobs if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) 3672264Sjacobs return; 3682264Sjacobs 3692264Sjacobs if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) 3708533SSonam.Gupta@Sun.COM == NULL) 3712264Sjacobs return; 3722264Sjacobs 3732264Sjacobs cache->printer->attributes = attributes; 3742264Sjacobs svc->cache = cache; 3752264Sjacobs 3763758Sjacobs (void) regcomp(&doc1_re, doc1_expr, REG_EXTENDED|REG_ICASE); 3773758Sjacobs (void) regcomp(&doc2_re, doc2_expr, REG_EXTENDED|REG_ICASE); 3783758Sjacobs /* process job related entries */ 3793758Sjacobs while (line[0] != '\0') { 3803758Sjacobs job_t *job = NULL; 3813758Sjacobs 3823758Sjacobs parse_lpd_job(svc, &job, fd, line, sizeof (line)); 3833758Sjacobs if (job == NULL) 3843758Sjacobs break; 3853758Sjacobs list_append(&cache->jobs, job); 3862264Sjacobs } 3872264Sjacobs 388*9206SSonam.Gupta@Sun.COM /* 389*9206SSonam.Gupta@Sun.COM * For remote windows printer set the printer-state 390*9206SSonam.Gupta@Sun.COM * after parse_lpd_job 391*9206SSonam.Gupta@Sun.COM */ 392*9206SSonam.Gupta@Sun.COM if (win_flag) { 393*9206SSonam.Gupta@Sun.COM if (state == 0x05) 394*9206SSonam.Gupta@Sun.COM win_state = state; 395*9206SSonam.Gupta@Sun.COM 396*9206SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 397*9206SSonam.Gupta@Sun.COM "printer-state", win_state); 398*9206SSonam.Gupta@Sun.COM } 3992264Sjacobs time(&cache->timestamp); 4002264Sjacobs } 4012264Sjacobs 4022264Sjacobs void 4032264Sjacobs cache_update(service_t *svc) 4042264Sjacobs { 4052264Sjacobs int fd; 4062264Sjacobs 4072264Sjacobs if (svc->cache != NULL) /* this should be time based */ 4082264Sjacobs return; 4092264Sjacobs 4102264Sjacobs if (svc == NULL) 4112264Sjacobs return; 4122264Sjacobs 4133915Sceastha if ((fd = lpd_open(svc, 'q', NULL, 15)) < 0) 4142264Sjacobs return; 4152264Sjacobs 4162264Sjacobs parse_lpd_query(svc, fd); 4172264Sjacobs 4182264Sjacobs close(fd); 4192264Sjacobs } 4202264Sjacobs 4212264Sjacobs papi_status_t 4222264Sjacobs lpd_find_printer_info(service_t *svc, printer_t **printer) 4232264Sjacobs { 4242264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4252264Sjacobs 4262264Sjacobs if ((svc == NULL) || (printer == NULL)) 4272264Sjacobs return (PAPI_BAD_ARGUMENT); 4282264Sjacobs 4292264Sjacobs cache_update(svc); 4302264Sjacobs 4312264Sjacobs if (svc->cache != NULL) { 4322264Sjacobs *printer = svc->cache->printer; 4332264Sjacobs result = PAPI_OK; 4342264Sjacobs } else 4352264Sjacobs result = PAPI_NOT_FOUND; 4362264Sjacobs 4372264Sjacobs return (result); 4382264Sjacobs } 4392264Sjacobs 4402264Sjacobs papi_status_t 4412264Sjacobs lpd_find_jobs_info(service_t *svc, job_t ***jobs) 4422264Sjacobs { 4432264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4442264Sjacobs 4452264Sjacobs if (svc != NULL) { 4462264Sjacobs cache_update(svc); 4472264Sjacobs 4482264Sjacobs if (svc->cache != NULL) { 4492264Sjacobs *jobs = svc->cache->jobs; 4502264Sjacobs result = PAPI_OK; 4512264Sjacobs } 4522264Sjacobs } 4532264Sjacobs 4542264Sjacobs return (result); 4552264Sjacobs } 4562264Sjacobs 4572264Sjacobs papi_status_t 4582264Sjacobs lpd_find_job_info(service_t *svc, int job_id, job_t **job) 4592264Sjacobs { 4602264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4612264Sjacobs job_t **jobs; 4622264Sjacobs 4632264Sjacobs if (lpd_find_jobs_info(svc, &jobs) != PAPI_OK) { 4642264Sjacobs int i; 4652264Sjacobs 4662264Sjacobs *job = NULL; 4672264Sjacobs for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { 4682264Sjacobs int id = -1; 4692264Sjacobs 4702264Sjacobs papiAttributeListGetInteger(jobs[i]->attributes, NULL, 4718533SSonam.Gupta@Sun.COM "job-id", &id); 4722264Sjacobs if (id == job_id) 4732264Sjacobs *job = jobs[i]; 4742264Sjacobs } 4752264Sjacobs 4762264Sjacobs if (*job != NULL) 4772264Sjacobs result = PAPI_OK; 4782264Sjacobs } 4792264Sjacobs 4802264Sjacobs return (result); 4812264Sjacobs } 4822264Sjacobs 4832264Sjacobs void 4842264Sjacobs cache_free(cache_t *item) 4852264Sjacobs { 4862264Sjacobs if (item != NULL) { 4872264Sjacobs if (item->printer != NULL) 4882264Sjacobs papiPrinterFree((papi_printer_t *)item->printer); 4892264Sjacobs if (item->jobs != NULL) 4902264Sjacobs papiJobListFree((papi_job_t *)item->jobs); 4912264Sjacobs free(item); 4922264Sjacobs } 4932264Sjacobs } 494