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