1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39#ifndef lint 40/* 41static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95"; 42*/ 43static const char rcsid[] =
| 1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39#ifndef lint 40/* 41static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95"; 42*/ 43static const char rcsid[] =
|
83 84 while ((c = getc(cfp)) != '\n' && linel+1 < sizeof(line)) { 85 if (c == EOF) 86 return(0); 87 if (c == '\t') { 88 do { 89 *lp++ = ' '; 90 linel++; 91 } while ((linel & 07) != 0 && linel+1 < sizeof(line)); 92 continue; 93 } 94 *lp++ = c; 95 linel++; 96 } 97 *lp++ = '\0'; 98 return(linel); 99} 100 101/* 102 * Scan the current directory and make a list of daemon files sorted by 103 * creation time. 104 * Return the number of entries and a pointer to the list. 105 */ 106int 107getq(pp, namelist) 108 const struct printer *pp; 109 struct queue *(*namelist[]); 110{ 111 register struct dirent *d; 112 register struct queue *q, **queue; 113 register int nitems; 114 struct stat stbuf; 115 DIR *dirp; 116 int arraysz; 117 118 seteuid(euid); 119 if ((dirp = opendir(pp->spool_dir)) == NULL) 120 return(-1); 121 if (fstat(dirp->dd_fd, &stbuf) < 0) 122 goto errdone; 123 seteuid(uid); 124 125 /* 126 * Estimate the array size by taking the size of the directory file 127 * and dividing it by a multiple of the minimum size entry. 128 */ 129 arraysz = (stbuf.st_size / 24); 130 queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); 131 if (queue == NULL) 132 goto errdone; 133 134 nitems = 0; 135 while ((d = readdir(dirp)) != NULL) { 136 if (d->d_name[0] != 'c' || d->d_name[1] != 'f') 137 continue; /* daemon control files only */ 138 seteuid(euid); 139 if (stat(d->d_name, &stbuf) < 0) 140 continue; /* Doesn't exist */ 141 seteuid(uid); 142 q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); 143 if (q == NULL) 144 goto errdone; 145 q->q_time = stbuf.st_mtime; 146 strcpy(q->q_name, d->d_name); 147 /* 148 * Check to make sure the array has space left and 149 * realloc the maximum size. 150 */ 151 if (++nitems > arraysz) { 152 arraysz *= 2; 153 queue = (struct queue **)realloc((char *)queue, 154 arraysz * sizeof(struct queue *)); 155 if (queue == NULL) 156 goto errdone; 157 } 158 queue[nitems-1] = q; 159 } 160 closedir(dirp); 161 if (nitems) 162 qsort(queue, nitems, sizeof(struct queue *), compar); 163 *namelist = queue; 164 return(nitems); 165 166errdone: 167 closedir(dirp); 168 return(-1); 169} 170 171/* 172 * Compare modification times. 173 */ 174static int 175compar(p1, p2) 176 const void *p1, *p2; 177{ 178 if ((*(struct queue **)p1)->q_time < (*(struct queue **)p2)->q_time) 179 return(-1); 180 if ((*(struct queue **)p1)->q_time > (*(struct queue **)p2)->q_time) 181 return(1); 182 return(0); 183} 184 185/* sleep n milliseconds */ 186void 187delay(n) 188 int n; 189{ 190 struct timeval tdelay; 191 192 if (n <= 0 || n > 10000) 193 fatal((struct printer *)0, /* fatal() knows how to deal */ 194 "unreasonable delay period (%d)", n); 195 tdelay.tv_sec = n / 1000; 196 tdelay.tv_usec = n * 1000 % 1000000; 197 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tdelay); 198} 199 200char * 201lock_file_name(pp, buf, len) 202 const struct printer *pp; 203 char *buf; 204 size_t len; 205{ 206 static char staticbuf[MAXPATHLEN]; 207 208 if (buf == 0) 209 buf = staticbuf; 210 if (len == 0) 211 len = MAXPATHLEN; 212 213 if (pp->lock_file[0] == '/') { 214 buf[0] = '\0'; 215 strncpy(buf, pp->lock_file, len); 216 } else { 217 snprintf(buf, len, "%s/%s", pp->spool_dir, pp->lock_file); 218 } 219 return buf; 220} 221 222char * 223status_file_name(pp, buf, len) 224 const struct printer *pp; 225 char *buf; 226 size_t len; 227{ 228 static char staticbuf[MAXPATHLEN]; 229 230 if (buf == 0) 231 buf = staticbuf; 232 if (len == 0) 233 len = MAXPATHLEN; 234 235 if (pp->status_file[0] == '/') { 236 buf[0] = '\0'; 237 strncpy(buf, pp->status_file, len); 238 } else { 239 snprintf(buf, len, "%s/%s", pp->spool_dir, pp->status_file); 240 } 241 return buf; 242} 243 244#ifdef __STDC__ 245#include <stdarg.h> 246#else 247#include <varargs.h> 248#endif 249 250void 251#ifdef __STDC__ 252fatal(const struct printer *pp, const char *msg, ...) 253#else 254fatal(pp, msg, va_alist) 255 const struct printer *pp; 256 char *msg; 257 va_dcl 258#endif 259{ 260 va_list ap; 261#ifdef __STDC__ 262 va_start(ap, msg); 263#else 264 va_start(ap); 265#endif 266 if (from != host) 267 (void)printf("%s: ", host); 268 (void)printf("%s: ", name); 269 if (pp && pp->printer) 270 (void)printf("%s: ", pp->printer); 271 (void)vprintf(msg, ap); 272 va_end(ap); 273 (void)putchar('\n'); 274 exit(1); 275} 276 277/* 278 * Close all file descriptors from START on up. 279 * This is a horrific kluge, since getdtablesize() might return 280 * ``infinity'', in which case we will be spending a long time 281 * closing ``files'' which were never open. Perhaps it would 282 * be better to close the first N fds, for some small value of N. 283 */ 284void 285closeallfds(start) 286 int start; 287{ 288 int stop = getdtablesize(); 289 for (; start < stop; start++) 290 close(start); 291} 292
| 83 84 while ((c = getc(cfp)) != '\n' && linel+1 < sizeof(line)) { 85 if (c == EOF) 86 return(0); 87 if (c == '\t') { 88 do { 89 *lp++ = ' '; 90 linel++; 91 } while ((linel & 07) != 0 && linel+1 < sizeof(line)); 92 continue; 93 } 94 *lp++ = c; 95 linel++; 96 } 97 *lp++ = '\0'; 98 return(linel); 99} 100 101/* 102 * Scan the current directory and make a list of daemon files sorted by 103 * creation time. 104 * Return the number of entries and a pointer to the list. 105 */ 106int 107getq(pp, namelist) 108 const struct printer *pp; 109 struct queue *(*namelist[]); 110{ 111 register struct dirent *d; 112 register struct queue *q, **queue; 113 register int nitems; 114 struct stat stbuf; 115 DIR *dirp; 116 int arraysz; 117 118 seteuid(euid); 119 if ((dirp = opendir(pp->spool_dir)) == NULL) 120 return(-1); 121 if (fstat(dirp->dd_fd, &stbuf) < 0) 122 goto errdone; 123 seteuid(uid); 124 125 /* 126 * Estimate the array size by taking the size of the directory file 127 * and dividing it by a multiple of the minimum size entry. 128 */ 129 arraysz = (stbuf.st_size / 24); 130 queue = (struct queue **)malloc(arraysz * sizeof(struct queue *)); 131 if (queue == NULL) 132 goto errdone; 133 134 nitems = 0; 135 while ((d = readdir(dirp)) != NULL) { 136 if (d->d_name[0] != 'c' || d->d_name[1] != 'f') 137 continue; /* daemon control files only */ 138 seteuid(euid); 139 if (stat(d->d_name, &stbuf) < 0) 140 continue; /* Doesn't exist */ 141 seteuid(uid); 142 q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1); 143 if (q == NULL) 144 goto errdone; 145 q->q_time = stbuf.st_mtime; 146 strcpy(q->q_name, d->d_name); 147 /* 148 * Check to make sure the array has space left and 149 * realloc the maximum size. 150 */ 151 if (++nitems > arraysz) { 152 arraysz *= 2; 153 queue = (struct queue **)realloc((char *)queue, 154 arraysz * sizeof(struct queue *)); 155 if (queue == NULL) 156 goto errdone; 157 } 158 queue[nitems-1] = q; 159 } 160 closedir(dirp); 161 if (nitems) 162 qsort(queue, nitems, sizeof(struct queue *), compar); 163 *namelist = queue; 164 return(nitems); 165 166errdone: 167 closedir(dirp); 168 return(-1); 169} 170 171/* 172 * Compare modification times. 173 */ 174static int 175compar(p1, p2) 176 const void *p1, *p2; 177{ 178 if ((*(struct queue **)p1)->q_time < (*(struct queue **)p2)->q_time) 179 return(-1); 180 if ((*(struct queue **)p1)->q_time > (*(struct queue **)p2)->q_time) 181 return(1); 182 return(0); 183} 184 185/* sleep n milliseconds */ 186void 187delay(n) 188 int n; 189{ 190 struct timeval tdelay; 191 192 if (n <= 0 || n > 10000) 193 fatal((struct printer *)0, /* fatal() knows how to deal */ 194 "unreasonable delay period (%d)", n); 195 tdelay.tv_sec = n / 1000; 196 tdelay.tv_usec = n * 1000 % 1000000; 197 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tdelay); 198} 199 200char * 201lock_file_name(pp, buf, len) 202 const struct printer *pp; 203 char *buf; 204 size_t len; 205{ 206 static char staticbuf[MAXPATHLEN]; 207 208 if (buf == 0) 209 buf = staticbuf; 210 if (len == 0) 211 len = MAXPATHLEN; 212 213 if (pp->lock_file[0] == '/') { 214 buf[0] = '\0'; 215 strncpy(buf, pp->lock_file, len); 216 } else { 217 snprintf(buf, len, "%s/%s", pp->spool_dir, pp->lock_file); 218 } 219 return buf; 220} 221 222char * 223status_file_name(pp, buf, len) 224 const struct printer *pp; 225 char *buf; 226 size_t len; 227{ 228 static char staticbuf[MAXPATHLEN]; 229 230 if (buf == 0) 231 buf = staticbuf; 232 if (len == 0) 233 len = MAXPATHLEN; 234 235 if (pp->status_file[0] == '/') { 236 buf[0] = '\0'; 237 strncpy(buf, pp->status_file, len); 238 } else { 239 snprintf(buf, len, "%s/%s", pp->spool_dir, pp->status_file); 240 } 241 return buf; 242} 243 244#ifdef __STDC__ 245#include <stdarg.h> 246#else 247#include <varargs.h> 248#endif 249 250void 251#ifdef __STDC__ 252fatal(const struct printer *pp, const char *msg, ...) 253#else 254fatal(pp, msg, va_alist) 255 const struct printer *pp; 256 char *msg; 257 va_dcl 258#endif 259{ 260 va_list ap; 261#ifdef __STDC__ 262 va_start(ap, msg); 263#else 264 va_start(ap); 265#endif 266 if (from != host) 267 (void)printf("%s: ", host); 268 (void)printf("%s: ", name); 269 if (pp && pp->printer) 270 (void)printf("%s: ", pp->printer); 271 (void)vprintf(msg, ap); 272 va_end(ap); 273 (void)putchar('\n'); 274 exit(1); 275} 276 277/* 278 * Close all file descriptors from START on up. 279 * This is a horrific kluge, since getdtablesize() might return 280 * ``infinity'', in which case we will be spending a long time 281 * closing ``files'' which were never open. Perhaps it would 282 * be better to close the first N fds, for some small value of N. 283 */ 284void 285closeallfds(start) 286 int start; 287{ 288 int stop = getdtablesize(); 289 for (; start < stop; start++) 290 close(start); 291} 292
|