1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 3125 jacobs * Common Development and Distribution License (the "License"). 6 3125 jacobs * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel 22 0 stevel /* 23 4321 casper * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 547 jacobs 27 547 jacobs /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 547 jacobs /* All Rights Reserved */ 29 0 stevel 30 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 31 0 stevel 32 0 stevel #include "lpsched.h" 33 0 stevel #include <syslog.h> 34 534 wendyp #include <strings.h> 35 0 stevel 36 0 stevel static char time_buf[50]; 37 0 stevel #ifdef LP_USE_PAPI_ATTR 38 0 stevel static char *extractReqno(char *req_file); 39 0 stevel #endif 40 0 stevel 41 0 stevel /** 42 0 stevel ** chfiles() - CHANGE OWNERSHIP OF FILES, RETURN TOTAL SIZE 43 0 stevel **/ 44 0 stevel 45 0 stevel off_t chfiles ( char * * list, uid_t uid, gid_t gid ) /* funcdef */ 46 0 stevel { 47 0 stevel size_t total; 48 0 stevel struct stat stbuf; 49 0 stevel char *file; 50 0 stevel 51 0 stevel total = 0; 52 0 stevel 53 0 stevel while(file = *list++) 54 0 stevel { 55 0 stevel if (STRNEQU(Lp_Temp, file, strlen(Lp_Temp)) || 56 0 stevel STRNEQU(Lp_Tmp, file, strlen(Lp_Tmp))) 57 0 stevel { 58 0 stevel /* 59 0 stevel * Once this routine (chfiles) is called for a request, 60 0 stevel * any temporary files are ``ours'', i.e. they are on our 61 0 stevel * machine. A user running on an RFS-connected remote machine 62 0 stevel * can't necessarily know our machine name, so can't put 63 0 stevel * the files where they belong (Lp_Tmp/machine). But now we 64 0 stevel * can. Of course, this is all done with mirrors, as Lp_Temp 65 0 stevel * and Lp_Tmp/local-machine are symbolicly linked. So we just 66 0 stevel * change the name. This saves on wear and tear later. 67 0 stevel */ 68 0 stevel if (STRNEQU(Lp_Temp, file, strlen(Lp_Temp))) 69 0 stevel { 70 0 stevel char *newfile = makepath(Lp_Tmp, Local_System, 71 0 stevel file + strlen(Lp_Temp) + 1, NULL); 72 0 stevel 73 0 stevel Free(file); 74 0 stevel list[-1] = file = newfile; 75 0 stevel } 76 0 stevel 77 547 jacobs (void) chownmod(file, uid, gid, 0600); 78 0 stevel } 79 0 stevel 80 0 stevel if (Stat(file, &stbuf) == -1) 81 0 stevel return(-1); 82 0 stevel 83 0 stevel switch (stbuf.st_mode & S_IFMT) { 84 0 stevel case 0: 85 0 stevel case S_IFREG: 86 0 stevel break; 87 0 stevel 88 0 stevel case S_IFIFO: 89 0 stevel if (!isadmin(uid)) 90 0 stevel return(-1); 91 0 stevel /* 92 0 stevel * If any of the files is a FIFO, the size indicator 93 0 stevel * becomes meaningless. On the other hand, returning 94 0 stevel * a total of zero causes the request to be rejected, 95 0 stevel * so we return something > 0. 96 0 stevel */ 97 0 stevel stbuf.st_size = 1; 98 0 stevel break; 99 0 stevel 100 0 stevel case S_IFDIR: 101 0 stevel case S_IFCHR: 102 0 stevel case S_IFBLK: 103 0 stevel default: 104 0 stevel return(-1); 105 0 stevel } 106 0 stevel 107 0 stevel total += stbuf.st_size; 108 0 stevel } 109 0 stevel return(total); 110 0 stevel } 111 0 stevel 112 0 stevel /** 113 0 stevel ** rmfiles() - DELETE/LOG FILES FOR DEFUNCT REQUEST 114 0 stevel **/ 115 0 stevel 116 0 stevel void rmfiles ( RSTATUS * rp, int log_it ) /* funcdef */ 117 0 stevel { 118 0 stevel char **file = rp->request->file_list; 119 0 stevel char *path; 120 0 stevel char num[STRSIZE(MOST_FILES) + 1]; 121 0 stevel static int fd = -1; 122 0 stevel int reqfd; 123 0 stevel int count = 0; 124 0 stevel #ifdef LP_USE_PAPI_ATTR 125 0 stevel struct stat tmpBuf; 126 0 stevel char *idno = NULL; 127 0 stevel char tmpName[BUFSIZ]; 128 0 stevel #endif 129 0 stevel 130 0 stevel 131 0 stevel if (rp->req_file) { 132 0 stevel char *p, *q; 133 0 stevel 134 0 stevel /* 135 0 stevel * The secure request file is removed first to prevent 136 0 stevel * reloading should the system crash while in rmfiles(). 137 0 stevel */ 138 0 stevel path = makepath(Lp_Requests, rp->req_file, (char *)0); 139 0 stevel (void) Unlink(path); 140 0 stevel Free(path); 141 0 stevel 142 0 stevel /* 143 0 stevel * Copy the request file to the log file, if asked, 144 0 stevel * or simply remove it. 145 0 stevel */ 146 0 stevel path = makepath(Lp_Tmp, rp->req_file, (char *)0); 147 0 stevel if (log_it && rp->secure && rp->secure->req_id) { 148 0 stevel if (fd == -1) 149 0 stevel fd = open_locked(Lp_ReqLog, "a", MODE_NOREAD); 150 0 stevel if ((fd >= 0) && (reqfd = Open(path, O_RDONLY, 0)) != -1) { 151 0 stevel register int n; 152 0 stevel char buf[BUFSIZ]; 153 0 stevel 154 0 stevel (void) strftime(time_buf, sizeof (time_buf), 155 0 stevel NULL, localtime(&(rp->secure->date))); 156 4321 casper fdprintf(fd, "= %s, uid %u, gid %u, size %ld, %s\n", 157 0 stevel rp->secure->req_id, rp->secure->uid, rp->secure->gid, 158 0 stevel rp->secure->size, time_buf); 159 0 stevel if (rp->slow) 160 0 stevel fdprintf(fd, "x %s\n", rp->slow); 161 0 stevel if (rp->fast) 162 0 stevel fdprintf(fd, "y %s\n", rp->fast); 163 3125 jacobs if (rp->printer && rp->printer->printer) 164 0 stevel fdprintf(fd, "z %s\n", rp->printer->printer->name); 165 0 stevel while ((n = Read(reqfd, buf, BUFSIZ)) > 0) 166 0 stevel write (fd, buf, n); 167 0 stevel Close (reqfd); 168 0 stevel } 169 0 stevel } 170 0 stevel (void)Unlink (path); /* remove request file */ 171 0 stevel Free (path); 172 0 stevel 173 0 stevel p = strdup(rp->req_file); /* remove host/id file */ 174 0 stevel if (q = strrchr(p, '-')) { 175 0 stevel *q = NULL; 176 0 stevel path = makepath(Lp_Tmp, p, NULL); 177 0 stevel (void) Unlink(path); 178 0 stevel Free(path); 179 0 stevel } 180 0 stevel Free(p); 181 0 stevel 182 0 stevel #ifdef LP_USE_PAPI_ATTR 183 0 stevel /* Look for a PAPI job attribute file, if it exists remove it */ 184 0 stevel idno = extractReqno(rp->req_file); 185 0 stevel snprintf(tmpName, sizeof (tmpName), "%s-%s", idno, LP_PAPIATTRNAME); 186 0 stevel path = makepath(Lp_Temp, tmpName, (char *)0); 187 0 stevel 188 0 stevel if (((path != NULL) && (idno != NULL)) && (stat(path, &tmpBuf) == 0)) 189 0 stevel { 190 0 stevel /* PAPI job attribute file exists for this job so remove it */ 191 0 stevel (void) Unlink(path); 192 0 stevel } 193 0 stevel 194 0 stevel Free(idno); 195 0 stevel Free(path); 196 0 stevel #endif 197 0 stevel } 198 0 stevel 199 0 stevel if (file) /* remove file in filelist */ 200 0 stevel while(*file) 201 0 stevel { 202 0 stevel /* 203 0 stevel * The copies of user files. 204 0 stevel */ 205 534 wendyp if ((STRNEQU(Lp_Temp, *file, strlen(Lp_Temp)) || 206 534 wendyp STRNEQU(Lp_Tmp, *file, strlen(Lp_Tmp))) && 207 534 wendyp (! strstr(*file, "../"))) 208 534 wendyp 209 0 stevel (void) Unlink(*file); 210 534 wendyp 211 0 stevel count++; 212 0 stevel file++; 213 0 stevel } 214 0 stevel 215 0 stevel if (rp->secure && rp->secure->req_id) { 216 0 stevel char *p; 217 0 stevel p = getreqno(rp->secure->req_id); 218 0 stevel 219 0 stevel /* 220 0 stevel * The filtered files. We can't rely on just the RS_FILTERED 221 0 stevel * flag, since the request may have been cancelled while 222 0 stevel * filtering. On the other hand, just checking "rp->slow" 223 0 stevel * doesn't mean that the files exist, because the request 224 0 stevel * may have been canceled BEFORE filtering started. Oh well. 225 0 stevel */ 226 0 stevel if (rp->slow) 227 0 stevel while(count > 0) 228 0 stevel { 229 0 stevel sprintf(num, "%d", count--); 230 3125 jacobs path = makestr(Lp_Temp, "/F", p, "-", num, (char *)0); 231 0 stevel Unlink(path); 232 0 stevel Free(path); 233 0 stevel } 234 0 stevel 235 0 stevel /* 236 0 stevel * The notify/error file. 237 0 stevel */ 238 0 stevel path = makepath(Lp_Temp, p, (char *)0); 239 0 stevel (void) Unlink(path); 240 0 stevel Free(path); 241 0 stevel } 242 0 stevel } 243 0 stevel 244 0 stevel /** 245 0 stevel ** _alloc_req_id(void) - ALLOCATE NEXT REQUEST ID 246 0 stevel **/ 247 0 stevel 248 0 stevel #define SEQF_DEF_START 1 249 0 stevel #define SEQF_DEF_END 59999 250 0 stevel #define SEQF_DEF_INCR 1 251 0 stevel #define SEQF ".SEQF" 252 0 stevel 253 0 stevel 254 0 stevel long 255 0 stevel _alloc_req_id ( void ) 256 0 stevel { 257 0 stevel static short started = 0; 258 0 stevel 259 0 stevel static int fd; 260 0 stevel 261 0 stevel static long start; 262 0 stevel static long end; 263 0 stevel static long incr; 264 0 stevel static long curr; 265 0 stevel static long wrap; 266 0 stevel 267 0 stevel static char fmt[ 268 0 stevel STRSIZE(BIGGEST_REQID_S)/* start */ 269 0 stevel + 1 /* : */ 270 0 stevel + STRSIZE(BIGGEST_REQID_S)/* end */ 271 0 stevel + 1 /* : */ 272 0 stevel + STRSIZE(BIGGEST_REQID_S)/* incr */ 273 0 stevel + 1 /* : */ 274 0 stevel + 4 /* %ld\n */ 275 0 stevel + 1 /* (nul) */ 276 0 stevel ]; 277 0 stevel 278 0 stevel char buf[256]; 279 0 stevel int len; 280 0 stevel 281 0 stevel long ret; 282 0 stevel 283 0 stevel 284 0 stevel if (!started) { 285 0 stevel snprintf(buf, sizeof (buf), "%s/%s", Lp_Temp, SEQF); 286 0 stevel if (((fd = open_locked(buf, "r+", 0644)) < 0) && 287 0 stevel ((fd = open_locked(buf, "w", 0644)) < 0)) 288 0 stevel fail ("Can't open file %s (%s).\n", buf, PERROR); 289 0 stevel 290 0 stevel lseek(fd, 0, SEEK_SET); 291 0 stevel 292 0 stevel read(fd, buf, sizeof (buf)); 293 0 stevel if (sscanf(buf, "%ld:%ld:%ld:%ld\n", &start, &end, &incr, &curr) != 4) { 294 0 stevel start = SEQF_DEF_START; 295 0 stevel end = SEQF_DEF_END; 296 0 stevel curr = start; 297 0 stevel incr = SEQF_DEF_INCR; 298 0 stevel } 299 0 stevel 300 0 stevel if (start < 0) 301 0 stevel start = SEQF_DEF_START; 302 0 stevel if (end > SEQF_DEF_END) 303 0 stevel end = SEQF_DEF_END; 304 0 stevel if (curr < start || curr > end) 305 0 stevel curr = start; 306 0 stevel 307 0 stevel sprintf (fmt, "%ld:%ld:%ld:%%ld\n", start, end, incr); 308 0 stevel started = 1; 309 0 stevel } 310 0 stevel 311 0 stevel wrap = curr; 312 0 stevel do { 313 0 stevel ret = curr; 314 0 stevel if ((curr += incr) > end) 315 0 stevel curr = start; 316 0 stevel 317 0 stevel } while ( wrap != curr && ((RSTATUS *)request_by_id_num(ret)) ) ; 318 0 stevel 319 0 stevel /* write the new id file */ 320 0 stevel lseek(fd, 0, SEEK_SET); 321 0 stevel len = sprintf(buf, fmt, curr); 322 0 stevel write(fd, buf, len); 323 0 stevel ftruncate(fd, len); 324 0 stevel 325 0 stevel if (curr == wrap) { 326 0 stevel note("alloc_req_id(): out of ids\n"); 327 0 stevel errno = EEXIST; 328 0 stevel return(SEQF_DEF_START-1); 329 0 stevel } else 330 0 stevel return (ret); 331 0 stevel } 332 0 stevel 333 0 stevel /** 334 0 stevel ** _alloc_file() - ALLOCATE FILES FOR A REQUEST 335 0 stevel **/ 336 0 stevel 337 0 stevel char * 338 0 stevel _alloc_files ( 339 0 stevel int num, 340 0 stevel char * prefix, 341 0 stevel uid_t uid, 342 3125 jacobs gid_t gid 343 0 stevel ) 344 0 stevel { 345 0 stevel static char base[ 346 0 stevel 1 /* F */ 347 0 stevel + STRSIZE(BIGGEST_REQID_S)/* req-id */ 348 0 stevel + 1 /* - */ 349 0 stevel + STRSIZE(MOST_FILES_S) /* file-no */ 350 0 stevel + 1 /* (nul) */ 351 0 stevel ]; 352 0 stevel 353 0 stevel char * file; 354 0 stevel char * cp; 355 0 stevel 356 0 stevel int fd; 357 0 stevel int plus; 358 0 stevel 359 0 stevel 360 0 stevel if (num > BIGGEST_REQID) 361 0 stevel return (0); 362 0 stevel 363 0 stevel if (!prefix) { 364 0 stevel int id; 365 0 stevel 366 0 stevel if ((id = _alloc_req_id()) < SEQF_DEF_START ) 367 0 stevel return(NULL); /* Out of request IDs (errno = EEXIST) */ 368 0 stevel snprintf (base, sizeof (base), "%d-%d", id, MOST_FILES); 369 0 stevel plus = 0; 370 0 stevel } else { 371 0 stevel if (strlen(prefix) > (size_t) 6) 372 0 stevel return (0); 373 0 stevel snprintf (base, sizeof (base), "F%s-%d", prefix, MOST_FILES); 374 0 stevel plus = 1; 375 0 stevel } 376 0 stevel 377 3125 jacobs file = makepath(Lp_Temp, base, (char *)0); 378 0 stevel 379 0 stevel cp = strrchr(file, '-') + 1; 380 0 stevel while (num--) { 381 0 stevel sprintf (cp, "%d", num + plus); 382 0 stevel if ((fd = Open(file, O_CREAT|O_TRUNC, 0600)) == -1) { 383 0 stevel Free (file); 384 0 stevel return (0); 385 0 stevel } else { 386 0 stevel Close (fd); 387 547 jacobs (void) chownmod(file, uid, gid, 0600); 388 0 stevel } 389 0 stevel } 390 0 stevel 391 0 stevel #ifdef LP_USE_PAPI_ATTR 392 0 stevel if (prefix == NULL) 393 0 stevel { 394 0 stevel /* 395 0 stevel * Initial job request (s_alloc_files) so create an empty PAPI 396 0 stevel * Attribute file; note, this file will only be used if the 397 0 stevel * print job has been submitted via the PAPI interface. 398 0 stevel */ 399 0 stevel 400 0 stevel file = (char *)Realloc(file, strlen(file) + 401 0 stevel strlen(LP_PAPIATTRNAME) + 1); 402 0 stevel if (file != NULL) 403 0 stevel { 404 0 stevel cp = strrchr(file, '-') + 1; 405 0 stevel sprintf(cp, "%s", LP_PAPIATTRNAME); 406 0 stevel 407 0 stevel if ((fd = Open(file, O_CREAT|O_TRUNC, 0600)) == -1) 408 0 stevel { 409 0 stevel Free(file); 410 0 stevel return (0); 411 0 stevel } 412 0 stevel else 413 0 stevel { 414 0 stevel Close(fd); 415 547 jacobs (void) chownmod(file, uid, gid, 0600); 416 0 stevel } 417 0 stevel 418 0 stevel Free(file); 419 0 stevel } 420 0 stevel } 421 0 stevel #endif 422 0 stevel 423 0 stevel 424 0 stevel if ((cp = strrchr(base, '-'))) 425 0 stevel *cp = 0; 426 0 stevel 427 0 stevel return (base); 428 0 stevel } 429 0 stevel 430 0 stevel 431 0 stevel #ifdef LP_USE_PAPI_ATTR 432 0 stevel static char *extractReqno(char *req_file) 433 0 stevel 434 0 stevel { 435 0 stevel char *start = NULL; 436 0 stevel char *end = NULL; 437 0 stevel char *result = NULL; 438 0 stevel 439 0 stevel start = strrchr(req_file, '/'); 440 0 stevel end = strrchr(req_file, '-'); 441 0 stevel 442 0 stevel if ((start != NULL) && (end != NULL)) 443 0 stevel { 444 0 stevel start++; 445 0 stevel if (end > start) 446 0 stevel { 447 0 stevel int n = end - start; 448 0 stevel result = (char *)Malloc(n+1); 449 0 stevel strncpy(result, start, n); 450 0 stevel result[n] = '\0'; 451 0 stevel } 452 0 stevel } 453 0 stevel 454 0 stevel return (result); 455 0 stevel } /* extractReqno() */ 456 0 stevel #endif 457