1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.12 */ 32 33 # include <errno.h> 34 # include <stdio.h> 35 # include <stdlib.h> 36 37 # include "lp.h" 38 # include "users.h" 39 40 static long pri; 41 42 /* 43 Input: Path name of the user priority file. It has the following 44 format: 45 1 line with a number representing the default priority level. 46 This must be the first line of the file, and no extra 47 white space is allowed between the priority value and 48 the newline. 49 1 line anywhere in the file with a number representing 50 the default priority limit. This number is followed 51 by a ':', and no extra white space is allowed. 52 any number of lines with a number followed by a ':', followed 53 by a white space (blank, tab or newline) separated 54 list of user names. No white space is allowed 55 between the priority value and the colon (:), but any 56 amount is ok in the UID list. 57 58 Note: If the default priority level is missing, a value of 20 will 59 be used. If the default limit is missing, zero will be used. 60 Also, the st_priority_file writes out the priority file in the 61 same order as the fields occur in the user_priority structure, 62 but the only order restriction is that the default level is 63 the first this. A priority level may occur more than once, and 64 this function will group them together (but the defaults may 65 only occur once, however the defaults may occur only once each. 66 67 Output: This function returns a pointer to a statically stored 68 structure containing the priority information. 69 70 Effect: The user priority file is read and parsed. Storage for 71 the priorities are allocated and loaded. In case of an error, 72 it prints out an error message, and returns 0 (NULL). 73 */ 74 75 struct user_priority * ld_priority_file ( char * path ) 76 { 77 char line[BUFSIZ], 78 *p, 79 *user, 80 *next_user(); 81 static struct user_priority pri_tbl; 82 int line_no = 1, 83 opri; 84 int fd; 85 86 if ((fd = open_locked(path, "r", 0)) < 0) { 87 if (errno == ENOENT) { 88 empty: 89 pri_tbl.deflt = LEVEL_DFLT; 90 pri_tbl.deflt_limit = LIMIT_DFLT; 91 memset ((char *)pri_tbl.users, 0, sizeof(pri_tbl.users)); 92 return (&pri_tbl); 93 } 94 return(0); 95 } 96 97 /* initialize table to empty */ 98 pri_tbl.deflt = -1; 99 pri_tbl.deflt_limit = -1; 100 memset ((char *)pri_tbl.users, 0, sizeof(pri_tbl.users)); 101 102 /* this loop reads the line containing the default priority, 103 if any, and the first priority limit. p is left pointing 104 to the colon (:) in the line with the first limit. */ 105 106 while (1) 107 { 108 if (!(p = fdgets(line, BUFSIZ, fd))) 109 goto empty; 110 p = line; 111 pri = strtol(line, &p, 10); 112 if (p == line) 113 goto Error; 114 if (pri < PRI_MIN || pri > PRI_MAX) 115 goto Error; 116 if (line_no == 1 && *p == '\n' && !p[1]) 117 pri_tbl.deflt = pri; 118 else 119 if (*p == ':') 120 { 121 p++; 122 break; 123 } 124 else 125 goto Error; 126 line_no++; 127 } 128 129 do 130 { 131 /* search list for this priority */ 132 opri = pri; 133 if (!(user = next_user(fd, line, &p))) 134 { 135 if (pri_tbl.deflt_limit == -1) 136 { 137 pri_tbl.deflt_limit = opri; 138 if (pri == -1) break; 139 if (!(user = next_user(fd, line, &p))) goto Error; 140 } 141 else 142 { 143 Error: 144 errno = EBADF; 145 close(fd); 146 return(0); 147 } 148 } 149 150 do 151 { 152 add_user (&pri_tbl, user, pri); 153 } 154 while ((user = next_user(fd, line, &p))); 155 } 156 while (pri != -1); 157 158 if (pri_tbl.deflt == -1) 159 pri_tbl.deflt = LEVEL_DFLT; 160 161 if (pri_tbl.deflt_limit == -1) 162 pri_tbl.deflt_limit = LIMIT_DFLT; 163 164 close(fd); 165 return (&pri_tbl); 166 } 167 168 /* 169 Inputs: A pointer to a limit structure, and a user. 170 Ouputs: The limit structure is modified. 171 Effects: Adds <user> to the list of users, if it is not already 172 there. 173 */ 174 175 int add_user ( struct user_priority * ppri_tbl, char * user, int limit ) 176 { 177 if (limit < PRI_MIN || PRI_MAX < limit) 178 return 1; 179 addlist (&(ppri_tbl->users[limit - PRI_MIN]), user); 180 return 0; 181 } 182 183 /* 184 Inputs: The input file to read additional lines, a pointer to 185 a buffer containing the current line, and to read additional 186 lines into, and a pointer to the location pointer (a pointer 187 into buf). 188 Outputs: The routine returns the next user-id read or 0 if all the 189 users for this priority are read. The buffer, the location 190 pointer, and the variable pri are modified as a side effect. 191 Effects: The input buffer is scanned starting at *pp for the next 192 user-id, if the end of the line is reached, the next line is 193 read from the file. If it scans the next priority value, the 194 variable pri (static to this file), is set to that priority. 195 EOF is indicated by setting this variable to -1, and also 196 returning 0. 197 */ 198 char * next_user (int fd, char * buf, char ** pp ) 199 { 200 long temp; 201 char *p; 202 static beg_line = 0; /* assumes a partial line is in buf to start */ 203 204 do 205 { 206 while (**pp == ' ' || **pp == '\n' || **pp == '\t') 207 (*pp)++; 208 p = *pp; 209 if (*p) 210 { 211 if (*p >= '0' && *p <= '9') 212 { 213 temp = strtol(p, pp, 10); 214 if (beg_line && **pp == ':') 215 { 216 (*pp)++; 217 pri = temp; 218 beg_line = 0; 219 return (0); 220 } 221 } 222 223 for (; **pp && **pp != ' ' && **pp != '\n' && **pp != '\t'; (*pp)++) 224 ; 225 if (**pp) 226 *(*pp)++ = 0; 227 beg_line = 0; 228 return (p); 229 } 230 beg_line = 1; 231 } 232 while (*pp = fdgets(buf, BUFSIZ, fd)); 233 234 pri = -1; 235 return (0); 236 } 237 238 /* 239 Inputs: A pointer to a priority table and a user. 240 Outputs: Zero if user found, else 1, and priority table is modified. 241 Effects: All occurences of <user> in the priority table will be removed. 242 (There should only be one at most.) 243 */ 244 int del_user ( struct user_priority * ppri_tbl, char * user ) 245 { 246 int limit; 247 248 for (limit = PRI_MIN; limit <= PRI_MAX; limit++) 249 if (searchlist(user, ppri_tbl->users[limit - PRI_MIN])) 250 { 251 dellist (&(ppri_tbl->users[limit - PRI_MIN]), user); 252 return (0); 253 } 254 return (1); 255 } 256