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*8533SSonam.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 */ 693758Sjacobs static char *job_expr = "^(.*[[:alnum:]]):[[:space:]]+([[:alnum:]]+)[[:space:]]+[[][[:space:]]*job[[:space:]]*([[:digit:]]+)[[:space:]]*(.*)]"; 703758Sjacobs static regex_t job_re; 713758Sjacobs 723758Sjacobs /* 73*8533SSonam.Gupta@Sun.COM * Print job entries for remote windows printer start with: 74*8533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 75*8533SSonam.Gupta@Sun.COM * e.g: 76*8533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 77*8533SSonam.Gupta@Sun.COM * ------------------------------------------------------------ 78*8533SSonam.Gupta@Sun.COM * root (10.3. Waiting /etc/release 2 240 1 4 79*8533SSonam.Gupta@Sun.COM * 80*8533SSonam.Gupta@Sun.COM * Owner is the job-owner's user name 81*8533SSonam.Gupta@Sun.COM * Status is the job-status (printing, waiting, error) 82*8533SSonam.Gupta@Sun.COM * Jobname is the name of the job to be printed 83*8533SSonam.Gupta@Sun.COM * Job-Id is the id of the job queued to be printed 84*8533SSonam.Gupta@Sun.COM * Size is the size of the job in bytes 85*8533SSonam.Gupta@Sun.COM * Pages is the number of pages of the job 86*8533SSonam.Gupta@Sun.COM * Priority is the job-priority 87*8533SSonam.Gupta@Sun.COM */ 88*8533SSonam.Gupta@Sun.COM static char *wjob_expr = "^([[:alnum:]]+)[[:space:]]*[(](.*)[)]*[[:space:]]+([[:alnum:]]+)[[:space:]]+(.*)([[:alnum:]]+)(.*)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)"; 89*8533SSonam.Gupta@Sun.COM static regex_t wjob_re; 90*8533SSonam.Gupta@Sun.COM 91*8533SSonam.Gupta@Sun.COM /* 92*8533SSonam.Gupta@Sun.COM * Windows job header is in the following format 93*8533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 94*8533SSonam.Gupta@Sun.COM * -------------------------------------------------------------- 95*8533SSonam.Gupta@Sun.COM */ 96*8533SSonam.Gupta@Sun.COM static char *whjob_expr = "Owner Status Jobname Job-Id Size Pages Priority"; 97*8533SSonam.Gupta@Sun.COM static regex_t whjob_re; 98*8533SSonam.Gupta@Sun.COM 99*8533SSonam.Gupta@Sun.COM static char *wline_expr = "----------"; 100*8533SSonam.Gupta@Sun.COM static regex_t wline_re; 101*8533SSonam.Gupta@Sun.COM 102*8533SSonam.Gupta@Sun.COM /* 1033758Sjacobs * status line(s) for "processing" printers will contain one of the following: 1043758Sjacobs * ready and printing 1053758Sjacobs * Printing 1063758Sjacobs */ 1073758Sjacobs static char *proc_expr = "(ready and printing|printing)"; 1083758Sjacobs static regex_t proc_re; 1093758Sjacobs 1103758Sjacobs /* 1113758Sjacobs * status line(s) for "idle" printers will contain one of the following: 1123758Sjacobs * no entries 1133758Sjacobs * (printer) is ready 1143758Sjacobs * idle 1153758Sjacobs */ 1163758Sjacobs static char *idle_expr = "(no entries|is ready| idle)"; 1173758Sjacobs static regex_t idle_re; 1183758Sjacobs 1193758Sjacobs /* 120*8533SSonam.Gupta@Sun.COM * Printer state reason 121*8533SSonam.Gupta@Sun.COM * Paused 122*8533SSonam.Gupta@Sun.COM */ 123*8533SSonam.Gupta@Sun.COM static char *state_reason_expr = "(Paused)"; 124*8533SSonam.Gupta@Sun.COM static regex_t state_reason_re; 125*8533SSonam.Gupta@Sun.COM 126*8533SSonam.Gupta@Sun.COM /* 1273758Sjacobs * document line(s) 1283758Sjacobs * (copies) copies of (name) (size) bytes 1293758Sjacobs * (name) (size) bytes 1303758Sjacobs * document lines can be in either format above. 1313758Sjacobs * (copies) is the number of copies of the document to print 1323758Sjacobs * (name) is the name of the document: /etc/motd, ... 1333758Sjacobs * (size) is the number of bytes in the document data 1343758Sjacobs */ 1353758Sjacobs static char *doc1_expr = "[[:space:]]+(([[:digit:]]+) copies of )([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes"; 1363758Sjacobs static char *doc2_expr = "[[:space:]]+()([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes"; 1373758Sjacobs static regex_t doc1_re; 1383758Sjacobs static regex_t doc2_re; 1393758Sjacobs 1403758Sjacobs static void 1413758Sjacobs parse_lpd_job(service_t *svc, job_t **job, int fd, char *line, int len) 1423758Sjacobs { 1432264Sjacobs papi_attribute_t **attributes = NULL; 144*8533SSonam.Gupta@Sun.COM regmatch_t matches[10]; 1453758Sjacobs char *s; 1462264Sjacobs int octets = 0; 147*8533SSonam.Gupta@Sun.COM int flag = 0; 1482264Sjacobs 149*8533SSonam.Gupta@Sun.COM /* 150*8533SSonam.Gupta@Sun.COM * job_re and wjob_re were compiled in the calling function 151*8533SSonam.Gupta@Sun.COM * first check for solaris jobs 152*8533SSonam.Gupta@Sun.COM * if there is no-match check for windows jobs 153*8533SSonam.Gupta@Sun.COM */ 1543758Sjacobs 155*8533SSonam.Gupta@Sun.COM if (regexec(&job_re, line, (size_t)5, matches, 0) == REG_NOMATCH) { 156*8533SSonam.Gupta@Sun.COM if (regexec(&wjob_re, line, (size_t)10, matches, 0) 157*8533SSonam.Gupta@Sun.COM == REG_NOMATCH) 158*8533SSonam.Gupta@Sun.COM return; 159*8533SSonam.Gupta@Sun.COM else 160*8533SSonam.Gupta@Sun.COM flag = 1; 161*8533SSonam.Gupta@Sun.COM } 162*8533SSonam.Gupta@Sun.COM 163*8533SSonam.Gupta@Sun.COM if (flag == 1) { 164*8533SSonam.Gupta@Sun.COM /* Windows job */ 165*8533SSonam.Gupta@Sun.COM /* first match is job-id */ 166*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 167*8533SSonam.Gupta@Sun.COM s = "nobody"; 168*8533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 169*8533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 170*8533SSonam.Gupta@Sun.COM 171*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 172*8533SSonam.Gupta@Sun.COM s = "unknown"; 173*8533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 174*8533SSonam.Gupta@Sun.COM "job-name", s); 175*8533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 176*8533SSonam.Gupta@Sun.COM "job-file-names", s); 1772264Sjacobs 178*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[7], line)) == NULL) 179*8533SSonam.Gupta@Sun.COM s = "0"; 180*8533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 181*8533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 182*8533SSonam.Gupta@Sun.COM 183*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[8], line)) == NULL) 184*8533SSonam.Gupta@Sun.COM s = "0"; 185*8533SSonam.Gupta@Sun.COM octets = atoi(s); 186*8533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, 187*8533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", atoi(s)); 1883758Sjacobs 189*8533SSonam.Gupta@Sun.COM } else { 190*8533SSonam.Gupta@Sun.COM /* Solaris job */ 191*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[1], line)) == NULL) 192*8533SSonam.Gupta@Sun.COM s = "nobody"; 193*8533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 194*8533SSonam.Gupta@Sun.COM "job-originating-user-name", s); 1953758Sjacobs 196*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[2], line)) == NULL) 197*8533SSonam.Gupta@Sun.COM s = "0"; 198*8533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 199*8533SSonam.Gupta@Sun.COM "number-of-intervening-jobs", atoi(s) - 1); 200*8533SSonam.Gupta@Sun.COM 201*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[3], line)) == NULL) 202*8533SSonam.Gupta@Sun.COM s = "0"; 203*8533SSonam.Gupta@Sun.COM papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 204*8533SSonam.Gupta@Sun.COM "job-id", atoi(s)); 205*8533SSonam.Gupta@Sun.COM 206*8533SSonam.Gupta@Sun.COM if ((s = regvalue(matches[4], line)) == NULL) 207*8533SSonam.Gupta@Sun.COM s = svc->uri->host; 208*8533SSonam.Gupta@Sun.COM papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 209*8533SSonam.Gupta@Sun.COM "job-originating-host-name", s); 210*8533SSonam.Gupta@Sun.COM } 2112264Sjacobs 2123758Sjacobs while ((fdgets(line, len, fd) != NULL) && 213*8533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 214*8533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 2153758Sjacobs int size = 0, copies = 1; 2163758Sjacobs /* process copies/documents */ 2172264Sjacobs 2183758Sjacobs /* doc1_re and doc2_re were compiled in the calling function */ 2193758Sjacobs if ((regexec(&doc1_re, line, (size_t)4, matches, 0) != 0) && 2203758Sjacobs (regexec(&doc2_re, line, (size_t)4, matches, 0) != 0)) 2213758Sjacobs continue; 2222264Sjacobs 2233758Sjacobs if ((s = regvalue(matches[1], line)) == NULL) 2243758Sjacobs s = "1"; 2253758Sjacobs if ((copies = atoi(s)) < 1) 2263758Sjacobs copies = 1; 2272264Sjacobs 2283758Sjacobs if ((s = regvalue(matches[2], line)) == NULL) 2293758Sjacobs s = "unknown"; 2303758Sjacobs papiAttributeListAddString(&attributes, 231*8533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-name", s); 2323758Sjacobs papiAttributeListAddString(&attributes, 233*8533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-names", s); 2342264Sjacobs 2353758Sjacobs if ((s = regvalue(matches[3], line)) == NULL) 2363758Sjacobs s = "0"; 2373758Sjacobs size = atoi(s); 238*8533SSonam.Gupta@Sun.COM 2393758Sjacobs papiAttributeListAddInteger(&attributes, 240*8533SSonam.Gupta@Sun.COM PAPI_ATTR_APPEND, "job-file-sizes", size); 2412264Sjacobs 2423758Sjacobs octets += (size * copies); 2432264Sjacobs } 2442264Sjacobs 2452264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 246*8533SSonam.Gupta@Sun.COM "job-k-octets", octets/1024); 2472264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 248*8533SSonam.Gupta@Sun.COM "job-octets", octets); 2492264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 250*8533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2512264Sjacobs 2522264Sjacobs if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) 2532264Sjacobs (*job)->attributes = attributes; 2542264Sjacobs } 2552264Sjacobs 2562264Sjacobs void 2572264Sjacobs parse_lpd_query(service_t *svc, int fd) 2582264Sjacobs { 2592264Sjacobs papi_attribute_t **attributes = NULL; 2602264Sjacobs cache_t *cache = NULL; 2612264Sjacobs int state = 0x03; /* idle */ 2622264Sjacobs char line[128]; 2633758Sjacobs char status[1024]; 2643758Sjacobs char *s; 2652264Sjacobs 2662264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 267*8533SSonam.Gupta@Sun.COM "printer-name", queue_name_from_uri(svc->uri)); 2682264Sjacobs 2693758Sjacobs if (uri_to_string(svc->uri, status, sizeof (status)) == 0) 2702264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 271*8533SSonam.Gupta@Sun.COM "printer-uri-supported", status); 2723758Sjacobs 2733758Sjacobs /* 2743758Sjacobs * on most systems, status is a single line, but some appear to 2753758Sjacobs * return multi-line status messages. To get the "best" possible 2763758Sjacobs * printer-state-reason, we accumulate the text until we hit the 2773758Sjacobs * first print job entry. 2783758Sjacobs * 2793758Sjacobs * Print job entries start with: 2803758Sjacobs * user: rank [job number ...] 2813758Sjacobs */ 2823758Sjacobs (void) regcomp(&job_re, job_expr, REG_EXTENDED|REG_ICASE); 2833758Sjacobs 284*8533SSonam.Gupta@Sun.COM /* 285*8533SSonam.Gupta@Sun.COM * For remote windows printers 286*8533SSonam.Gupta@Sun.COM * Print job entries start with: 287*8533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 288*8533SSonam.Gupta@Sun.COM */ 289*8533SSonam.Gupta@Sun.COM (void) regcomp(&wjob_re, wjob_expr, REG_EXTENDED|REG_ICASE); 290*8533SSonam.Gupta@Sun.COM (void) regcomp(&whjob_re, whjob_expr, REG_EXTENDED|REG_ICASE); 291*8533SSonam.Gupta@Sun.COM (void) regcomp(&wline_re, wline_expr, REG_EXTENDED|REG_ICASE); 292*8533SSonam.Gupta@Sun.COM 2933758Sjacobs status[0] = '\0'; 294*8533SSonam.Gupta@Sun.COM 2953758Sjacobs while ((fdgets(line, sizeof (line), fd) != NULL) && 296*8533SSonam.Gupta@Sun.COM (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && 297*8533SSonam.Gupta@Sun.COM (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { 298*8533SSonam.Gupta@Sun.COM /* 299*8533SSonam.Gupta@Sun.COM * When windows job queue gets queried following header 300*8533SSonam.Gupta@Sun.COM * should not get printed 301*8533SSonam.Gupta@Sun.COM * Owner Status Jobname Job-Id Size Pages Priority 302*8533SSonam.Gupta@Sun.COM * ----------------------------------------------- 303*8533SSonam.Gupta@Sun.COM */ 304*8533SSonam.Gupta@Sun.COM if ((regexec(&whjob_re, line, (size_t)0, NULL, 0) 305*8533SSonam.Gupta@Sun.COM == REG_NOMATCH) && (regexec(&wline_re, line, (size_t)0, NULL, 0) 306*8533SSonam.Gupta@Sun.COM == REG_NOMATCH)) 307*8533SSonam.Gupta@Sun.COM strlcat(status, line, sizeof (status)); 3083758Sjacobs } 309*8533SSonam.Gupta@Sun.COM 3103758Sjacobs /* chop off trailing whitespace */ 3113758Sjacobs s = status + strlen(status) - 1; 3123758Sjacobs while ((s > status) && (isspace(*s) != 0)) 3133758Sjacobs *s-- = '\0'; 3142264Sjacobs 3152264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 316*8533SSonam.Gupta@Sun.COM "printer-state-reasons", status); 3172264Sjacobs 3183758Sjacobs (void) regcomp(&proc_re, proc_expr, REG_EXTENDED|REG_ICASE); 3193758Sjacobs (void) regcomp(&idle_re, idle_expr, REG_EXTENDED|REG_ICASE); 320*8533SSonam.Gupta@Sun.COM (void) regcomp(&state_reason_re, state_reason_expr, 321*8533SSonam.Gupta@Sun.COM REG_EXTENDED|REG_ICASE); 322*8533SSonam.Gupta@Sun.COM 323*8533SSonam.Gupta@Sun.COM if ((regexec(&proc_re, status, (size_t)0, NULL, 0) == 0) || 324*8533SSonam.Gupta@Sun.COM (regexec(&state_reason_re, status, (size_t)0, NULL, 0) == 325*8533SSonam.Gupta@Sun.COM REG_NOMATCH)) 3262264Sjacobs state = 0x04; /* processing */ 3273758Sjacobs else if (regexec(&idle_re, status, (size_t)0, NULL, 0) == 0) 3282264Sjacobs state = 0x03; /* idle */ 3292264Sjacobs else 3302264Sjacobs state = 0x05; /* stopped */ 3312264Sjacobs 3322264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 333*8533SSonam.Gupta@Sun.COM "printer-state", state); 3342264Sjacobs 3352264Sjacobs if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) 3362264Sjacobs return; 3372264Sjacobs 3382264Sjacobs if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) 339*8533SSonam.Gupta@Sun.COM == NULL) 3402264Sjacobs return; 3412264Sjacobs 3422264Sjacobs cache->printer->attributes = attributes; 3432264Sjacobs svc->cache = cache; 3442264Sjacobs 3453758Sjacobs (void) regcomp(&doc1_re, doc1_expr, REG_EXTENDED|REG_ICASE); 3463758Sjacobs (void) regcomp(&doc2_re, doc2_expr, REG_EXTENDED|REG_ICASE); 3473758Sjacobs /* process job related entries */ 3483758Sjacobs while (line[0] != '\0') { 3493758Sjacobs job_t *job = NULL; 3503758Sjacobs 3513758Sjacobs parse_lpd_job(svc, &job, fd, line, sizeof (line)); 3523758Sjacobs if (job == NULL) 3533758Sjacobs break; 3543758Sjacobs list_append(&cache->jobs, job); 3552264Sjacobs } 3562264Sjacobs 3572264Sjacobs time(&cache->timestamp); 3582264Sjacobs } 3592264Sjacobs 3602264Sjacobs void 3612264Sjacobs cache_update(service_t *svc) 3622264Sjacobs { 3632264Sjacobs int fd; 3642264Sjacobs 3652264Sjacobs if (svc->cache != NULL) /* this should be time based */ 3662264Sjacobs return; 3672264Sjacobs 3682264Sjacobs if (svc == NULL) 3692264Sjacobs return; 3702264Sjacobs 3713915Sceastha if ((fd = lpd_open(svc, 'q', NULL, 15)) < 0) 3722264Sjacobs return; 3732264Sjacobs 3742264Sjacobs parse_lpd_query(svc, fd); 3752264Sjacobs 3762264Sjacobs close(fd); 3772264Sjacobs } 3782264Sjacobs 3792264Sjacobs papi_status_t 3802264Sjacobs lpd_find_printer_info(service_t *svc, printer_t **printer) 3812264Sjacobs { 3822264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 3832264Sjacobs 3842264Sjacobs if ((svc == NULL) || (printer == NULL)) 3852264Sjacobs return (PAPI_BAD_ARGUMENT); 3862264Sjacobs 3872264Sjacobs cache_update(svc); 3882264Sjacobs 3892264Sjacobs if (svc->cache != NULL) { 3902264Sjacobs *printer = svc->cache->printer; 3912264Sjacobs result = PAPI_OK; 3922264Sjacobs } else 3932264Sjacobs result = PAPI_NOT_FOUND; 3942264Sjacobs 3952264Sjacobs return (result); 3962264Sjacobs } 3972264Sjacobs 3982264Sjacobs papi_status_t 3992264Sjacobs lpd_find_jobs_info(service_t *svc, job_t ***jobs) 4002264Sjacobs { 4012264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4022264Sjacobs 4032264Sjacobs if (svc != NULL) { 4042264Sjacobs cache_update(svc); 4052264Sjacobs 4062264Sjacobs if (svc->cache != NULL) { 4072264Sjacobs *jobs = svc->cache->jobs; 4082264Sjacobs result = PAPI_OK; 4092264Sjacobs } 4102264Sjacobs } 4112264Sjacobs 4122264Sjacobs return (result); 4132264Sjacobs } 4142264Sjacobs 4152264Sjacobs papi_status_t 4162264Sjacobs lpd_find_job_info(service_t *svc, int job_id, job_t **job) 4172264Sjacobs { 4182264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 4192264Sjacobs job_t **jobs; 4202264Sjacobs 4212264Sjacobs if (lpd_find_jobs_info(svc, &jobs) != PAPI_OK) { 4222264Sjacobs int i; 4232264Sjacobs 4242264Sjacobs *job = NULL; 4252264Sjacobs for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { 4262264Sjacobs int id = -1; 4272264Sjacobs 4282264Sjacobs papiAttributeListGetInteger(jobs[i]->attributes, NULL, 429*8533SSonam.Gupta@Sun.COM "job-id", &id); 4302264Sjacobs if (id == job_id) 4312264Sjacobs *job = jobs[i]; 4322264Sjacobs } 4332264Sjacobs 4342264Sjacobs if (*job != NULL) 4352264Sjacobs result = PAPI_OK; 4362264Sjacobs } 4372264Sjacobs 4382264Sjacobs return (result); 4392264Sjacobs } 4402264Sjacobs 4412264Sjacobs void 4422264Sjacobs cache_free(cache_t *item) 4432264Sjacobs { 4442264Sjacobs if (item != NULL) { 4452264Sjacobs if (item->printer != NULL) 4462264Sjacobs papiPrinterFree((papi_printer_t *)item->printer); 4472264Sjacobs if (item->jobs != NULL) 4482264Sjacobs papiJobListFree((papi_job_t *)item->jobs); 4492264Sjacobs free(item); 4502264Sjacobs } 4512264Sjacobs } 452