1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs 22*2264Sjacobs /* 23*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2264Sjacobs * Use is subject to license terms. 25*2264Sjacobs * 26*2264Sjacobs */ 27*2264Sjacobs 28*2264Sjacobs /* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */ 29*2264Sjacobs 30*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31*2264Sjacobs 32*2264Sjacobs #define __EXTENSIONS__ /* for strtok_r() */ 33*2264Sjacobs #include <stdio.h> 34*2264Sjacobs #include <stdlib.h> 35*2264Sjacobs #include <unistd.h> 36*2264Sjacobs #include <sys/types.h> 37*2264Sjacobs #include <sys/stat.h> 38*2264Sjacobs #include <sys/fcntl.h> 39*2264Sjacobs #include <time.h> 40*2264Sjacobs #include <ctype.h> 41*2264Sjacobs #include <string.h> 42*2264Sjacobs #include <stdarg.h> 43*2264Sjacobs 44*2264Sjacobs #include <papi_impl.h> 45*2264Sjacobs 46*2264Sjacobs static void 47*2264Sjacobs parse_lpd_job_entry(service_t *svc, int fd, job_t **job) 48*2264Sjacobs { 49*2264Sjacobs char *iter = NULL; 50*2264Sjacobs char line[128]; 51*2264Sjacobs papi_attribute_t **attributes = NULL; 52*2264Sjacobs char *p; 53*2264Sjacobs int octets = 0; 54*2264Sjacobs 55*2264Sjacobs *job = NULL; 56*2264Sjacobs 57*2264Sjacobs if (fdgets(line, sizeof (line), fd) == NULL) 58*2264Sjacobs return; 59*2264Sjacobs /* 60*2264Sjacobs * 1st line... 61*2264Sjacobs * user: rank [job (ID)(host)]\n 62*2264Sjacobs */ 63*2264Sjacobs if ((p = strtok_r(line, ": ", &iter)) == NULL) /* user: ... */ 64*2264Sjacobs return; /* invalid format */ 65*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 66*2264Sjacobs "job-originating-user-name", p); 67*2264Sjacobs 68*2264Sjacobs p = strtok_r(NULL, "\t ", &iter); /* ...rank... */ 69*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 70*2264Sjacobs "number-of-intervening-jobs", atoi(p) - 1); 71*2264Sjacobs p = strtok_r(NULL, " ", &iter); /* ...[job ... */ 72*2264Sjacobs if ((p = strtok_r(NULL, "]\n", &iter)) == NULL) /* ...(id)(hostname)] */ 73*2264Sjacobs return; 74*2264Sjacobs while (isspace(*p)) p++; 75*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 76*2264Sjacobs "job-id", atoi(p)); 77*2264Sjacobs while (isdigit(*(++p))); 78*2264Sjacobs while (isspace(*p)) p++; 79*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 80*2264Sjacobs "job-originating-host-name", p); 81*2264Sjacobs 82*2264Sjacobs /* 83*2264Sjacobs * rest-o-lines 84*2264Sjacobs * [(num) copies of ]file size bytes\n 85*2264Sjacobs */ 86*2264Sjacobs while ((fdgets(line, sizeof (line), fd) != NULL) && (line[0] != '\n')) { 87*2264Sjacobs int copies, size; 88*2264Sjacobs char *q; 89*2264Sjacobs 90*2264Sjacobs /* find the number of copies */ 91*2264Sjacobs if ((p = strstr(line, "copies of")) != NULL) { 92*2264Sjacobs copies = atoi(line); 93*2264Sjacobs p += 9; 94*2264Sjacobs } else { 95*2264Sjacobs copies = 1; 96*2264Sjacobs p = line; 97*2264Sjacobs } 98*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL, 99*2264Sjacobs "copies", copies); 100*2264Sjacobs 101*2264Sjacobs /* eat the leading whitespace */ 102*2264Sjacobs while (isspace(*p) != 0) 103*2264Sjacobs p++; 104*2264Sjacobs if ((q = strstr(p, " bytes\n")) != NULL) { 105*2264Sjacobs /* back up to the beginning of the size */ 106*2264Sjacobs do { q--; } while (isdigit(*q) != 0); 107*2264Sjacobs 108*2264Sjacobs /* seperate the name and size */ 109*2264Sjacobs *q = '\0'; 110*2264Sjacobs q++; 111*2264Sjacobs 112*2264Sjacobs size = atoi(q); 113*2264Sjacobs 114*2264Sjacobs papiAttributeListAddString(&attributes, 115*2264Sjacobs PAPI_ATTR_APPEND, "job-name", p); 116*2264Sjacobs papiAttributeListAddString(&attributes, 117*2264Sjacobs PAPI_ATTR_APPEND, "job-file-names", p); 118*2264Sjacobs papiAttributeListAddInteger(&attributes, 119*2264Sjacobs PAPI_ATTR_APPEND, "job-file-sizes", size); 120*2264Sjacobs 121*2264Sjacobs octets += (size * copies); 122*2264Sjacobs } 123*2264Sjacobs } 124*2264Sjacobs 125*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 126*2264Sjacobs "job-k-octets", octets/1024); 127*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, 128*2264Sjacobs "job-octets", octets); 129*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 130*2264Sjacobs "printer-name", queue_name_from_uri(svc->uri)); 131*2264Sjacobs 132*2264Sjacobs if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) 133*2264Sjacobs (*job)->attributes = attributes; 134*2264Sjacobs } 135*2264Sjacobs 136*2264Sjacobs static void 137*2264Sjacobs parse_lpd_job_entries(service_t *svc, int fd) 138*2264Sjacobs { 139*2264Sjacobs job_t *job = NULL; 140*2264Sjacobs 141*2264Sjacobs do { 142*2264Sjacobs parse_lpd_job_entry(svc, fd, &job); 143*2264Sjacobs list_append(&svc->cache->jobs, job); 144*2264Sjacobs } while (job != NULL); 145*2264Sjacobs 146*2264Sjacobs } 147*2264Sjacobs 148*2264Sjacobs 149*2264Sjacobs void 150*2264Sjacobs parse_lpd_query(service_t *svc, int fd) 151*2264Sjacobs { 152*2264Sjacobs papi_attribute_t **attributes = NULL; 153*2264Sjacobs cache_t *cache = NULL; 154*2264Sjacobs int state = 0x03; /* idle */ 155*2264Sjacobs char line[128]; 156*2264Sjacobs char buf[1024]; 157*2264Sjacobs 158*2264Sjacobs /* get the status line */ 159*2264Sjacobs if (fdgets(line, sizeof (line), fd) == NULL) 160*2264Sjacobs return; /* this should not happen. */ 161*2264Sjacobs 162*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 163*2264Sjacobs "printer-name", queue_name_from_uri(svc->uri)); 164*2264Sjacobs 165*2264Sjacobs if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0) 166*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, 167*2264Sjacobs "printer-uri-supported", buf); 168*2264Sjacobs 169*2264Sjacobs papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, 170*2264Sjacobs "printer-state-reasons", line); 171*2264Sjacobs 172*2264Sjacobs if (strstr(line, "ready and printing") != NULL) 173*2264Sjacobs state = 0x04; /* processing */ 174*2264Sjacobs else if ((strstr(line, "no entries") != NULL) || 175*2264Sjacobs (strstr(line, "is ready") != NULL)) 176*2264Sjacobs state = 0x03; /* idle */ 177*2264Sjacobs else 178*2264Sjacobs state = 0x05; /* stopped */ 179*2264Sjacobs 180*2264Sjacobs papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, 181*2264Sjacobs "printer-state", state); 182*2264Sjacobs 183*2264Sjacobs if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) 184*2264Sjacobs return; 185*2264Sjacobs 186*2264Sjacobs if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) 187*2264Sjacobs == NULL) 188*2264Sjacobs return; 189*2264Sjacobs 190*2264Sjacobs cache->printer->attributes = attributes; 191*2264Sjacobs svc->cache = cache; 192*2264Sjacobs 193*2264Sjacobs if (fdgets(line, sizeof (line), fd) != NULL) { 194*2264Sjacobs /* get the jobs */ 195*2264Sjacobs parse_lpd_job_entries(svc, fd); 196*2264Sjacobs } 197*2264Sjacobs 198*2264Sjacobs time(&cache->timestamp); 199*2264Sjacobs } 200*2264Sjacobs 201*2264Sjacobs void 202*2264Sjacobs cache_update(service_t *svc) 203*2264Sjacobs { 204*2264Sjacobs int fd; 205*2264Sjacobs 206*2264Sjacobs if (svc->cache != NULL) /* this should be time based */ 207*2264Sjacobs return; 208*2264Sjacobs 209*2264Sjacobs if (svc == NULL) 210*2264Sjacobs return; 211*2264Sjacobs 212*2264Sjacobs if ((fd = lpd_open(svc, 'q', NULL, 3)) < 0) 213*2264Sjacobs return; 214*2264Sjacobs 215*2264Sjacobs parse_lpd_query(svc, fd); 216*2264Sjacobs 217*2264Sjacobs close(fd); 218*2264Sjacobs } 219*2264Sjacobs 220*2264Sjacobs papi_status_t 221*2264Sjacobs lpd_find_printer_info(service_t *svc, printer_t **printer) 222*2264Sjacobs { 223*2264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 224*2264Sjacobs 225*2264Sjacobs if ((svc == NULL) || (printer == NULL)) 226*2264Sjacobs return (PAPI_BAD_ARGUMENT); 227*2264Sjacobs 228*2264Sjacobs cache_update(svc); 229*2264Sjacobs 230*2264Sjacobs if (svc->cache != NULL) { 231*2264Sjacobs *printer = svc->cache->printer; 232*2264Sjacobs result = PAPI_OK; 233*2264Sjacobs } else 234*2264Sjacobs result = PAPI_NOT_FOUND; 235*2264Sjacobs 236*2264Sjacobs return (result); 237*2264Sjacobs } 238*2264Sjacobs 239*2264Sjacobs papi_status_t 240*2264Sjacobs lpd_find_jobs_info(service_t *svc, job_t ***jobs) 241*2264Sjacobs { 242*2264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 243*2264Sjacobs 244*2264Sjacobs if (svc != NULL) { 245*2264Sjacobs cache_update(svc); 246*2264Sjacobs 247*2264Sjacobs if (svc->cache != NULL) { 248*2264Sjacobs *jobs = svc->cache->jobs; 249*2264Sjacobs result = PAPI_OK; 250*2264Sjacobs } 251*2264Sjacobs } 252*2264Sjacobs 253*2264Sjacobs return (result); 254*2264Sjacobs } 255*2264Sjacobs 256*2264Sjacobs papi_status_t 257*2264Sjacobs lpd_find_job_info(service_t *svc, int job_id, job_t **job) 258*2264Sjacobs { 259*2264Sjacobs papi_status_t result = PAPI_BAD_ARGUMENT; 260*2264Sjacobs job_t **jobs; 261*2264Sjacobs 262*2264Sjacobs if (lpd_find_jobs_info(svc, &jobs) != PAPI_OK) { 263*2264Sjacobs int i; 264*2264Sjacobs 265*2264Sjacobs *job = NULL; 266*2264Sjacobs for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { 267*2264Sjacobs int id = -1; 268*2264Sjacobs 269*2264Sjacobs papiAttributeListGetInteger(jobs[i]->attributes, NULL, 270*2264Sjacobs "job-id", &id); 271*2264Sjacobs if (id == job_id) 272*2264Sjacobs *job = jobs[i]; 273*2264Sjacobs } 274*2264Sjacobs 275*2264Sjacobs if (*job != NULL) 276*2264Sjacobs result = PAPI_OK; 277*2264Sjacobs } 278*2264Sjacobs 279*2264Sjacobs return (result); 280*2264Sjacobs } 281*2264Sjacobs 282*2264Sjacobs void 283*2264Sjacobs cache_free(cache_t *item) 284*2264Sjacobs { 285*2264Sjacobs if (item != NULL) { 286*2264Sjacobs if (item->printer != NULL) 287*2264Sjacobs papiPrinterFree((papi_printer_t *)item->printer); 288*2264Sjacobs if (item->jobs != NULL) 289*2264Sjacobs papiJobListFree((papi_job_t *)item->jobs); 290*2264Sjacobs free(item); 291*2264Sjacobs } 292*2264Sjacobs } 293