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 /* 23*12778SKeerthi.Kondaka@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 242264Sjacobs */ 252264Sjacobs 262264Sjacobs /* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */ 272264Sjacobs 282264Sjacobs #include <stdio.h> 292264Sjacobs #include <stdlib.h> 302264Sjacobs #include <unistd.h> 312264Sjacobs #include <sys/types.h> 322264Sjacobs #include <sys/stat.h> 332264Sjacobs #include <sys/fcntl.h> 342264Sjacobs #include <time.h> 352264Sjacobs #include <ctype.h> 362264Sjacobs #include <string.h> 372264Sjacobs #include <stdarg.h> 383758Sjacobs #include <regex.h> 392264Sjacobs 402264Sjacobs #include <papi_impl.h> 412264Sjacobs 423758Sjacobs /* The string is modified by this call */ 433758Sjacobs static char * 443758Sjacobs regvalue(regmatch_t match, char *string) 452264Sjacobs { 463758Sjacobs char *result = NULL; 473758Sjacobs 483758Sjacobs if (match.rm_so != match.rm_eo) { 493758Sjacobs result = string + match.rm_so; 503758Sjacobs *(result + (match.rm_eo - match.rm_so)) = '\0'; 513758Sjacobs } 523758Sjacobs 533758Sjacobs return (result); 543758Sjacobs } 553758Sjacobs 563758Sjacobs /* 573758Sjacobs * Print job entries start with: 583758Sjacobs * (user): (rank) [job (number) (...)] 593758Sjacobs * (user) is the job-owner's user name 603758Sjacobs * (rank) is the rank in queue. (active, 1st, 2nd, ...) 613758Sjacobs * (number) is the job number 623758Sjacobs * (...) is an optional hostname 633758Sjacobs * some servers will use whitespace a little differently than is displayed 643758Sjacobs * above. The regular expression below makes whitespace optional in some 653758Sjacobs * places. 663758Sjacobs */ 679206SSonam.Gupta@Sun.COM static char *job_expr = "^(.*[[:alnum:]]):[[:space:]]+([[:alnum:]]+)"\ 689206SSonam.Gupta@Sun.COM "[[:space:]]+[[][[:space:]]*job[[:space:]]*([[:digit:]]+)"\ 699206SSonam.Gupta@Sun.COM "[[:space:]]*(.*)]"; 703758Sjacobs static regex_t job_re; 713758Sjacobs 723758Sjacobs /* 738533SSonam.Gupta@Sun.COM * Print job entries for remote windows printer start with: 748533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 758533SSonam.Gupta@Sun.COM * e.g: 768533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 778533SSonam.Gupta@Sun.COM * ------------------------------------------------------------ 788533SSonam.Gupta@Sun.COM * root (10.3. Waiting /etc/release 2 240 1 4 798533SSonam.Gupta@Sun.COM * 808533SSonam.Gupta@Sun.COM * Owner is the job-owner's user name 818533SSonam.Gupta@Sun.COM * Status is the job-status (printing, waiting, error) 828533SSonam.Gupta@Sun.COM * Jobname is the name of the job to be printed 838533SSonam.Gupta@Sun.COM * Job-Id is the id of the job queued to be printed 848533SSonam.Gupta@Sun.COM * Size is the size of the job in bytes 858533SSonam.Gupta@Sun.COM * Pages is the number of pages of the job 868533SSonam.Gupta@Sun.COM * Priority is the job-priority 878533SSonam.Gupta@Sun.COM */ 889206SSonam.Gupta@Sun.COM static char *wjob_expr = "^([[:alnum:]]+)[[:space:]]*[(](.*)[)]*[[:space:]]"\ 899206SSonam.Gupta@Sun.COM "+([[:alnum:]]+)[[:space:]]+(.*)([[:alnum:]]+)(.*)[[:space:]]+"\ 909206SSonam.Gupta@Sun.COM "([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)"\ 919206SSonam.Gupta@Sun.COM "[[:space:]]+([[:digit:]]+)"; 928533SSonam.Gupta@Sun.COM static regex_t wjob_re; 938533SSonam.Gupta@Sun.COM 948533SSonam.Gupta@Sun.COM /* 958533SSonam.Gupta@Sun.COM * Windows job header is in the following format 968533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 978533SSonam.Gupta@Sun.COM * -------------------------------------------------------------- 988533SSonam.Gupta@Sun.COM */ 999206SSonam.Gupta@Sun.COM static char *whjob_expr = "Owner Status Jobname Job-Id"\ 1009206SSonam.Gupta@Sun.COM " Size Pages Priority"; 1018533SSonam.Gupta@Sun.COM static regex_t whjob_re; 1028533SSonam.Gupta@Sun.COM 1038533SSonam.Gupta@Sun.COM static char *wline_expr = "----------"; 1048533SSonam.Gupta@Sun.COM static regex_t wline_re; 1058533SSonam.Gupta@Sun.COM 1068533SSonam.Gupta@Sun.COM /* 1073758Sjacobs * status line(s) for "processing" printers will contain one of the following: 1083758Sjacobs * ready and printing 1093758Sjacobs * Printing 1109206SSonam.Gupta@Sun.COM * processing 1113758Sjacobs */ 1129206SSonam.Gupta@Sun.COM static char *proc_expr = "(ready and printing|printing|processing)"; 1133758Sjacobs static regex_t proc_re; 1143758Sjacobs 1153758Sjacobs /* 1163758Sjacobs * status line(s) for "idle" printers will contain one of the following: 1173758Sjacobs * no entries 1183758Sjacobs * (printer) is ready 1193758Sjacobs * idle 1203758Sjacobs */ 1213758Sjacobs static char *idle_expr = "(no entries|is ready| idle)"; 1223758Sjacobs static regex_t idle_re; 1233758Sjacobs 1243758Sjacobs /* 1259206SSonam.Gupta@Sun.COM * Printer state reason (For Windows remote printers) 1268533SSonam.Gupta@Sun.COM * Paused 1278533SSonam.Gupta@Sun.COM */ 1288533SSonam.Gupta@Sun.COM static char *state_reason_expr = "(Paused)"; 1298533SSonam.Gupta@Sun.COM static regex_t state_reason_re; 1308533SSonam.Gupta@Sun.COM 1318533SSonam.Gupta@Sun.COM /* 1323758Sjacobs * document line(s) 1333758Sjacobs * (copies) copies of (name) (size) bytes 1343758Sjacobs * (name) (size) bytes 1353758Sjacobs * document lines can be in either format above. 1363758Sjacobs * (copies) is the number of copies of the document to print 1373758Sjacobs * (name) is the name of the document: /etc/motd, ... 1383758Sjacobs * (size) is the number of bytes in the document data 1393758Sjacobs */ 1409206SSonam.Gupta@Sun.COM static char *doc1_expr = "[[:space:]]+(([[:digit:]]+) copies of )"\ 1419206SSonam.Gupta@Sun.COM "([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes"; 1429206SSonam.Gupta@Sun.COM static char *doc2_expr = "[[:space:]]+()([^[:space:]]+)[[:space:]]*"\ 1439206SSonam.Gupta@Sun.COM "([[:digit:]]+) bytes"; 1443758Sjacobs static regex_t doc1_re; 1453758Sjacobs static regex_t doc2_re; 1463758Sjacobs 1479206SSonam.Gupta@Sun.COM /* Printer-state for Windows */ 1489206SSonam.Gupta@Sun.COM static int win_state = 0x03; /* Idle */ 1499206SSonam.Gupta@Sun.COM 1503758Sjacobs static void 1513758Sjacobs parse_lpd_job(service_t *svc, job_t **job, int fd, char *line, int len) 1523758Sjacobs { 1532264Sjacobs papi_attribute_t **attributes = NULL; 1548533SSonam.Gupta@Sun.COM regmatch_t matches[10]; 1553758Sjacobs char *s; 1562264Sjacobs int octets = 0; 1578533SSonam.Gupta@Sun.COM int flag = 0; 1582264Sjacobs 1598533SSonam.Gupta@Sun.COM /* 1608533SSonam.Gupta@Sun.COM * job_re and wjob_re were compiled in the calling function 1618533SSonam.Gupta@Sun.COM * first check for solaris jobs 1628533SSonam.Gupta@Sun.COM * if there is no-match check for windows jobs 1638533SSonam.Gupta@Sun.COM */ 1643758Sjacobs 1658533SSonam.Gupta@Sun.COM if (regexec(&job_re, line, (size_t)5, matches, 0) == REG_NOMATCH) { 1668533SSonam.Gupta@Sun.COM if (regexec(&wjob_re, line, (size_t)10, matches, 0) 1678533SSonam.Gupta@Sun.COM == REG_NOMATCH) 1688533SSonam.Gupta@Sun.COM return; 1698533SSonam.Gupta@Sun.COM else 1708533SSonam.Gupta@Sun.COM flag = 1; 1718533SSonam.Gupta@Sun.COM } 1728533SSonam.Gupta@Sun.COM 1738533SSonam.Gupta@Sun.COM if (flag == 1) { 1748533SSonam.Gupta@Sun.COM /* Windows job */ 1758533SSonam.Gupta@Sun.COM /* first match is job-id */ 1769206SSonam.Gupta@Sun.COM 1778533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 1788533SSonam.Gupta@Sun.COM s = "nobody"; 1798533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 1808533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 1818533SSonam.Gupta@Sun.COM 1828533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 1838533SSonam.Gupta@Sun.COM s = "unknown"; 1848533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 1858533SSonam.Gupta@Sun.COM "job-name", s); 1868533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 1878533SSonam.Gupta@Sun.COM "job-file-names", s); 1882264Sjacobs 1898533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[7], line)) == NULL) 1908533SSonam.Gupta@Sun.COM s = "0"; 1918533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 1928533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 1938533SSonam.Gupta@Sun.COM 1948533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[8], line)) == NULL) 1958533SSonam.Gupta@Sun.COM s = "0"; 1968533SSonam.Gupta@Sun.COM octets = atoi(s); 1978533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, 1988533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", atoi(s)); 1993758Sjacobs 2009206SSonam.Gupta@Sun.COM /* 2019206SSonam.Gupta@Sun.COM * Since a job has been found so the printer state is either 2029206SSonam.Gupta@Sun.COM * 'stopped' or 'processing' 2039206SSonam.Gupta@Sun.COM * By default it is "processing" 2049206SSonam.Gupta@Sun.COM */ 2059206SSonam.Gupta@Sun.COM win_state = 0x04; 2068533SSonam.Gupta@Sun.COM } else { 2078533SSonam.Gupta@Sun.COM /* Solaris job */ 2088533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 2098533SSonam.Gupta@Sun.COM s = "nobody"; 2108533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 2118533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 2123758Sjacobs 2138533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[2], line)) == NULL) 2148533SSonam.Gupta@Sun.COM s = "0"; 2158533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 2168533SSonam.Gupta@Sun.COM "number-of-intervening-jobs", atoi(s) - 1); 2178533SSonam.Gupta@Sun.COM 2188533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[3], line)) == NULL) 2198533SSonam.Gupta@Sun.COM s = "0"; 2208533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 2218533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 2228533SSonam.Gupta@Sun.COM 2238533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 2248533SSonam.Gupta@Sun.COM s = svc->uri->host; 2258533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 2268533SSonam.Gupta@Sun.COM "job-originating-host-name", s); 2278533SSonam.Gupta@Sun.COM } 2282264Sjacobs 2293758Sjacobs while ((fdgets(line, len, fd) != NULL) && 2308533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 2318533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 2323758Sjacobs int size = 0, copies = 1; 2333758Sjacobs /* process copies/documents */ 2342264Sjacobs 2353758Sjacobs /* doc1_re and doc2_re were compiled in the calling function */ 2363758Sjacobs if ((regexec(&doc1_re, line, (size_t)4, matches, 0) != 0) && 2373758Sjacobs (regexec(&doc2_re, line, (size_t)4, matches, 0) != 0)) 2383758Sjacobs continue; 2392264Sjacobs 2403758Sjacobs if ((s = regvalue(matches[1], line)) == NULL) 2413758Sjacobs s = "1"; 2423758Sjacobs if ((copies = atoi(s)) < 1) 2433758Sjacobs copies = 1; 2442264Sjacobs 2453758Sjacobs if ((s = regvalue(matches[2], line)) == NULL) 2463758Sjacobs s = "unknown"; 2473758Sjacobs papiAttributeListAddString(&attributes, 2488533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-name", s); 2493758Sjacobs papiAttributeListAddString(&attributes, 2508533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-names", s); 2512264Sjacobs 2523758Sjacobs if ((s = regvalue(matches[3], line)) == NULL) 2533758Sjacobs s = "0"; 2543758Sjacobs size = atoi(s); 2558533SSonam.Gupta@Sun.COM 2563758Sjacobs papiAttributeListAddInteger(&attributes, 2578533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", size); 2582264Sjacobs 2593758Sjacobs octets += (size * copies); 2602264Sjacobs } 2612264Sjacobs 2622264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 2638533SSonam.Gupta@Sun.COM "job-k-octets", octets/1024); 2642264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 2658533SSonam.Gupta@Sun.COM "job-octets", octets); 2662264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2678533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2682264Sjacobs 2692264Sjacobs if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) 2702264Sjacobs (*job)->attributes = attributes; 2712264Sjacobs } 2722264Sjacobs 2732264Sjacobs void 2742264Sjacobs parse_lpd_query(service_t *svc, int fd) 2752264Sjacobs { 2762264Sjacobs papi_attribute_t **attributes = NULL; 2772264Sjacobs cache_t *cache = NULL; 2782264Sjacobs int state = 0x03; /* idle */ 2792264Sjacobs char line[128]; 2803758Sjacobs char status[1024]; 2813758Sjacobs char *s; 2829206SSonam.Gupta@Sun.COM int win_flag = 0; 2832264Sjacobs 2842264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2858533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2862264Sjacobs 2873758Sjacobs if (uri_to_string(svc->uri, status, sizeof (status)) == 0) 2882264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 2898533SSonam.Gupta@Sun.COM "printer-uri-supported", status); 2903758Sjacobs 2913758Sjacobs /* 2923758Sjacobs * on most systems, status is a single line, but some appear to 2933758Sjacobs * return multi-line status messages. To get the "best" possible 2943758Sjacobs * printer-state-reason, we accumulate the text until we hit the 2953758Sjacobs * first print job entry. 2963758Sjacobs * 2973758Sjacobs * Print job entries start with: 2983758Sjacobs * user: rank [job number ...] 2993758Sjacobs */ 3003758Sjacobs (void) regcomp(&job_re, job_expr, REG_EXTENDED|REG_ICASE); 3013758Sjacobs 3028533SSonam.Gupta@Sun.COM /* 3038533SSonam.Gupta@Sun.COM * For remote windows printers 3048533SSonam.Gupta@Sun.COM * Print job entries start with: 3058533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 3068533SSonam.Gupta@Sun.COM */ 3078533SSonam.Gupta@Sun.COM (void) regcomp(&wjob_re, wjob_expr, REG_EXTENDED|REG_ICASE); 3088533SSonam.Gupta@Sun.COM (void) regcomp(&whjob_re, whjob_expr, REG_EXTENDED|REG_ICASE); 3098533SSonam.Gupta@Sun.COM (void) regcomp(&wline_re, wline_expr, REG_EXTENDED|REG_ICASE); 3108533SSonam.Gupta@Sun.COM 3113758Sjacobs status[0] = '\0'; 3128533SSonam.Gupta@Sun.COM 3133758Sjacobs while ((fdgets(line, sizeof (line), fd) != NULL) && 3148533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 3158533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 3168533SSonam.Gupta@Sun.COM /* 3178533SSonam.Gupta@Sun.COM * When windows job queue gets queried following header 3188533SSonam.Gupta@Sun.COM * should not get printed 3198533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 3208533SSonam.Gupta@Sun.COM * ----------------------------------------------- 3218533SSonam.Gupta@Sun.COM */ 3228533SSonam.Gupta@Sun.COM if ((regexec(&whjob_re, line, (size_t)0, NULL, 0) 3239206SSonam.Gupta@Sun.COM == REG_NOMATCH) && 3249206SSonam.Gupta@Sun.COM (regexec(&wline_re, line, (size_t)0, NULL, 0) 3258533SSonam.Gupta@Sun.COM == REG_NOMATCH)) 3268533SSonam.Gupta@Sun.COM strlcat(status, line, sizeof (status)); 3273758Sjacobs } 3288533SSonam.Gupta@Sun.COM 3293758Sjacobs /* chop off trailing whitespace */ 3303758Sjacobs s = status + strlen(status) - 1; 3313758Sjacobs while ((s > status) && (isspace(*s) != 0)) 3323758Sjacobs *s-- = '\0'; 3332264Sjacobs 3342264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 3358533SSonam.Gupta@Sun.COM "printer-state-reasons", status); 3362264Sjacobs 3379206SSonam.Gupta@Sun.COM /* Check if this is for Windows remote printers */ 3389206SSonam.Gupta@Sun.COM if (strstr(status, "Windows")) { 3399206SSonam.Gupta@Sun.COM /* 3409206SSonam.Gupta@Sun.COM * It is a remote windows printer 3419206SSonam.Gupta@Sun.COM * By default set the status as idle 3429206SSonam.Gupta@Sun.COM * Set the printer-state after call to "parse_lpd_job" 3439206SSonam.Gupta@Sun.COM */ 3449206SSonam.Gupta@Sun.COM win_flag = 1; 3459206SSonam.Gupta@Sun.COM (void) regcomp(&state_reason_re, state_reason_expr, 3469206SSonam.Gupta@Sun.COM REG_EXTENDED|REG_ICASE); 3478533SSonam.Gupta@Sun.COM 3489206SSonam.Gupta@Sun.COM if (regexec(&state_reason_re, status, (size_t)0, NULL, 0) == 0) 3499206SSonam.Gupta@Sun.COM state = 0x05; /* stopped */ 3509206SSonam.Gupta@Sun.COM } else { 3519206SSonam.Gupta@Sun.COM (void) regcomp(&proc_re, proc_expr, REG_EXTENDED|REG_ICASE); 3529206SSonam.Gupta@Sun.COM (void) regcomp(&idle_re, idle_expr, REG_EXTENDED|REG_ICASE); 3532264Sjacobs 3549206SSonam.Gupta@Sun.COM if (regexec(&proc_re, status, (size_t)0, NULL, 0) == 0) 3559206SSonam.Gupta@Sun.COM state = 0x04; /* processing */ 3569206SSonam.Gupta@Sun.COM else if (regexec(&idle_re, status, (size_t)0, NULL, 0) == 0) 3579206SSonam.Gupta@Sun.COM state = 0x03; /* idle */ 3589206SSonam.Gupta@Sun.COM else 3599206SSonam.Gupta@Sun.COM state = 0x05; /* stopped */ 3609206SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 3619206SSonam.Gupta@Sun.COM "printer-state", state); 3629206SSonam.Gupta@Sun.COM } 3632264Sjacobs 3642264Sjacobs if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) 3652264Sjacobs return; 3662264Sjacobs 3672264Sjacobs if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) 3688533SSonam.Gupta@Sun.COM == NULL) 3692264Sjacobs return; 3702264Sjacobs 3712264Sjacobs cache->printer->attributes = attributes; 3722264Sjacobs svc->cache = cache; 3732264Sjacobs 3743758Sjacobs (void) regcomp(&doc1_re, doc1_expr, REG_EXTENDED|REG_ICASE); 3753758Sjacobs (void) regcomp(&doc2_re, doc2_expr, REG_EXTENDED|REG_ICASE); 3763758Sjacobs /* process job related entries */ 3773758Sjacobs while (line[0] != '\0') { 3783758Sjacobs job_t *job = NULL; 3793758Sjacobs 3803758Sjacobs parse_lpd_job(svc, &job, fd, line, sizeof (line)); 3813758Sjacobs if (job == NULL) 3823758Sjacobs break; 3833758Sjacobs list_append(&cache->jobs, job); 3842264Sjacobs } 3852264Sjacobs 3869206SSonam.Gupta@Sun.COM /* 3879206SSonam.Gupta@Sun.COM * For remote windows printer set the printer-state 3889206SSonam.Gupta@Sun.COM * after parse_lpd_job 3899206SSonam.Gupta@Sun.COM */ 3909206SSonam.Gupta@Sun.COM if (win_flag) { 3919206SSonam.Gupta@Sun.COM if (state == 0x05) 3929206SSonam.Gupta@Sun.COM win_state = state; 3939206SSonam.Gupta@Sun.COM 3949206SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 3959206SSonam.Gupta@Sun.COM "printer-state", win_state); 3969206SSonam.Gupta@Sun.COM } 3972264Sjacobs time(&cache->timestamp); 3982264Sjacobs } 3992264Sjacobs 4002264Sjacobs void 4012264Sjacobs cache_update(service_t *svc) 4022264Sjacobs { 4032264Sjacobs int fd; 4042264Sjacobs 405*12778SKeerthi.Kondaka@Sun.COM if (svc == NULL) 4062264Sjacobs return; 4072264Sjacobs 408*12778SKeerthi.Kondaka@Sun.COM if (svc->cache != NULL) { /* this should be time based */ 409*12778SKeerthi.Kondaka@Sun.COM if (svc->cache->jobs == NULL) { 410*12778SKeerthi.Kondaka@Sun.COM free(svc->cache); 411*12778SKeerthi.Kondaka@Sun.COM svc->cache = NULL; 412*12778SKeerthi.Kondaka@Sun.COM } else 413*12778SKeerthi.Kondaka@Sun.COM return; 414*12778SKeerthi.Kondaka@Sun.COM } 4152264Sjacobs 4163915Sceastha if ((fd = lpd_open(svc, 'q', NULL, 15)) < 0) 4172264Sjacobs return; 4182264Sjacobs 4192264Sjacobs parse_lpd_query(svc, fd); 4202264Sjacobs 4212264Sjacobs close(fd); 4222264Sjacobs } 4232264Sjacobs 4242264Sjacobs papi_status_t 4252264Sjacobs lpd_find_printer_info(service_t *svc, printer_t **printer) 4262264Sjacobs { 4272264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4282264Sjacobs 4292264Sjacobs if ((svc == NULL) || (printer == NULL)) 4302264Sjacobs return (PAPI_BAD_ARGUMENT); 4312264Sjacobs 4322264Sjacobs cache_update(svc); 4332264Sjacobs 4342264Sjacobs if (svc->cache != NULL) { 4352264Sjacobs *printer = svc->cache->printer; 4362264Sjacobs result = PAPI_OK; 4372264Sjacobs } else 4382264Sjacobs result = PAPI_NOT_FOUND; 4392264Sjacobs 4402264Sjacobs return (result); 4412264Sjacobs } 4422264Sjacobs 4432264Sjacobs papi_status_t 4442264Sjacobs lpd_find_jobs_info(service_t *svc, job_t ***jobs) 4452264Sjacobs { 4462264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4472264Sjacobs 4482264Sjacobs if (svc != NULL) { 4492264Sjacobs cache_update(svc); 4502264Sjacobs 4512264Sjacobs if (svc->cache != NULL) { 4522264Sjacobs *jobs = svc->cache->jobs; 4532264Sjacobs result = PAPI_OK; 4542264Sjacobs } 4552264Sjacobs } 4562264Sjacobs 457*12778SKeerthi.Kondaka@Sun.COM /* 458*12778SKeerthi.Kondaka@Sun.COM * cache jobs is free()-ed in 459*12778SKeerthi.Kondaka@Sun.COM * libpapi-dynamic/common/printer.c - 460*12778SKeerthi.Kondaka@Sun.COM * papiPrinterListJobs() cache printer is 461*12778SKeerthi.Kondaka@Sun.COM * free()-ed by the caller of 462*12778SKeerthi.Kondaka@Sun.COM * lpd_find_printer_info Invalidate the 463*12778SKeerthi.Kondaka@Sun.COM * cache by freeing the cache. 464*12778SKeerthi.Kondaka@Sun.COM */ 465*12778SKeerthi.Kondaka@Sun.COM free(svc->cache); 466*12778SKeerthi.Kondaka@Sun.COM svc->cache = NULL; 467*12778SKeerthi.Kondaka@Sun.COM 4682264Sjacobs return (result); 4692264Sjacobs } 4702264Sjacobs 4712264Sjacobs papi_status_t 4722264Sjacobs lpd_find_job_info(service_t *svc, int job_id, job_t **job) 4732264Sjacobs { 4742264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4752264Sjacobs job_t **jobs; 4762264Sjacobs 477*12778SKeerthi.Kondaka@Sun.COM if ((lpd_find_jobs_info(svc, &jobs) == PAPI_OK) && (jobs != NULL)) { 4782264Sjacobs int i; 4792264Sjacobs 4802264Sjacobs *job = NULL; 4812264Sjacobs for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { 4822264Sjacobs int id = -1; 4832264Sjacobs 4842264Sjacobs papiAttributeListGetInteger(jobs[i]->attributes, NULL, 4858533SSonam.Gupta@Sun.COM "job-id", &id); 4862264Sjacobs if (id == job_id) 4872264Sjacobs *job = jobs[i]; 4882264Sjacobs } 4892264Sjacobs 4902264Sjacobs if (*job != NULL) 4912264Sjacobs result = PAPI_OK; 4922264Sjacobs } 4932264Sjacobs 4942264Sjacobs return (result); 4952264Sjacobs } 4962264Sjacobs 4972264Sjacobs void 4982264Sjacobs cache_free(cache_t *item) 4992264Sjacobs { 5002264Sjacobs if (item != NULL) { 5012264Sjacobs if (item->printer != NULL) 5022264Sjacobs papiPrinterFree((papi_printer_t *)item->printer); 5032264Sjacobs if (item->jobs != NULL) 5042264Sjacobs papiJobListFree((papi_job_t *)item->jobs); 5052264Sjacobs free(item); 5062264Sjacobs } 5072264Sjacobs } 508