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