1 /* The code should compile with either ANSI C or K&R compilers. */
2 
3 /*
4  *      Copyright (c) 1995, 1996 by William Deich.
5  *      Written by William Deich.  Not derived from licensed software.
6 
7  *    You may distribute under the terms of either the GNU General Public
8  *    License or the Artistic License, as specified in the README file.
9  */
10 
11 /* Use P__() to have prototypes in STD C code, and not use
12  * prototypes in K&R C: declare functions as:
13  *	func_type  funcname P__((arglist));
14  */
15 
16 /* ==================================================================== */
17 
18 #include "localsys.h"
19 #include "s_hsearch.h"
20 #include "version.h"
21 
22 /* ==================================================================== */
23 
24 #ifndef __STDC__
25     extern char *malloc();
26     extern char *realloc();
27 #endif
28 
29 #ifndef HAVE_ALNUM
30 #define alnum(c) (isalpha(c) || isdigit(c))
31 #endif
32 
33 #define SEP	" \t\v\n"		/* How to split fields on input lines */
34 #define QM	"\"'"			/* Quotemarks in fields */
35 #define CM	"#"			/* Comments in input file */
36 #define SAFE_IFS "IFS= \t\n"
37 #define OPTION_SEP '='			/* option separator */
38 #define CONDITION_SEP '~'		/* condition separator */
39 
40 #define CLEAR_SETTINGS NULL
41 
42 /* The safe path should normally be defined/edited in config.h.  This is
43  * a just-in-case-it's-missing definition.
44  */
45 #ifndef SAFE_PATH
46 #define SAFE_PATH "/bin:/usr/bin:/usr/ucb"
47 #endif
48 
49 /* The name under this program assumes it is installed.  If argv[0] isn't
50  * [/.../]ONETRUENAME, we assume we're running via symlink.
51  */
52 #ifndef ONETRUENAME
53 #define ONETRUENAME "super"
54 #endif
55 
56 /* Kind of help we give */
57 #define HELP_BASIC	0	/* Basic help shows what you can execute */
58 #define HELP_FULL	1	/* Full help on each command */
59 #define HELP_FACTS	2	/* Just-the-facts-ma'm mode */
60 #define HELP_USAGE	3	/* Print usage only, no per-cmd help */
61 
62 #ifndef SUPERFILE
63 #ifdef SUPERDIR
64 #define SUPERFILE SUPERDIR "/super.tab"
65 #else
66 #define SUPERFILE "/usr/local/lib/super.tab"
67 #endif
68 #endif
69 
70 #ifndef PERUSER_SUPERFILE
71 #define PERUSER_SUPERFILE ".supertab"
72 #endif
73 
74 #ifndef MAXFD
75 int getdtablesize P__(( void ));
76 #define MAXFD (getdtablesize()-1)
77 #endif
78 
79 #ifndef MAXHOSTNAMELEN
80 #define MAXHOSTNAMELEN 256
81 #endif
82 
83 /* MAXSETENV is maximum number of variables that can be setenv'd on a
84  * super control line.  This isn't the maximum that can be passed; it's
85  * only the number of environment variables definitions that can be
86  * made on one control line.
87  */
88 #define MAXSETENV 40
89 
90 /* Default value for the maximum length of a user-supplied environment
91  * variable definition.
92  */
93 #define MAXENVLEN 1000
94 
95 /* If defined, then user patterns are allowed to match the uid as well as
96  * the actual username.  We DISABLE this by default because users are
97  * almost always identified by username.
98  */
99 /* #define MATCH_DECIMAL_UID */
100 
101 /* If defined, then group patterns are allowed to match the
102  * gid as well as the group name, if any.  We ENABLE this by default
103  * because it's not unusual for users to be put into unnamed groups
104  * in the password file.
105  */
106 #define MATCH_DECIMAL_GID
107 
108 /* maximum number of tries at entering the password */
109 #define MAXTRY 3
110 
111 /* default maxlength per arg passed to a command, maxlength all args */
112 #define MAXLEN1ARG 1000
113 #define MAXLENARGS 10000
114 
115 /* define max length per option passed to super (not to the referenced
116  * command), the max total length, and the valid option pattern.
117  */
118 #define MAXOPTLEN 250
119 #define MAXOPTLEN_TOT 500
120 #define OPT_PATTERN "^[-/:+.=%@!,_a-zA-Z0-9]*$"
121 
122 #ifdef HAVE_INNETGR
123 extern int innetgr();
124 #endif
125 
126 #ifndef HAVE_MEMSET
127 void *memset P__(( void *s, int c, size_t n ));
128 #endif
129 
130 /* special code to indicate we haven't specified a uid yet */
131 #define UID_NOTSET ((uid_t) ~0)
132 
133 /* special code to indicate we haven't specified a gid yet */
134 #define GID_NOTSET ((gid_t) ~0)
135 
136 /* special code to indicate we haven't specified supplementary groups */
137 #define GROUPS_NOTSET ((GETGROUPS_T) ~0)
138 
139 
140 /* Number of elements in an array */
141 #define NELEM(x) (sizeof(x)/(sizeof(*x)))
142 
143 /* n rounded up to a multiple of m -- both should be positive */
144 #define ROUNDUP(n, m) ( ((n) % (m) == 0) ? (n) : ((n)/(m) + 1)*(m) )
145 
146 /* STRBEG evaluates to !0 if s1 begins with substring s2 */
147 #define STRBEG(s1, s2) (strncmp((s1), (s2), strlen(s2)) == 0)
148 
149 /* STRMATCH3 expects 'end' to be a pointer into s2, and evaluates to !0
150  * if characters s2..(end-1) fully match s1 (that is, the next character in
151  * s1 is null.
152  */
153 #define STRMATCH3(s1, s2, end) \
154 	       (strncmp(s1, s2, end-s2) == 0 && s1[end-s2]=='\0')
155 
156 
157 #define UNTIL(e) while(!(e))
158 
159 /* ========================================================================= */
160 
161 /*
162  * Super's main external variables
163  */
164     extern char *prog;			/* this program */
165     extern int debug;			/* debug level; 0=off */
166     extern int check_syntax;		/* just check syntax of superfile */
167     extern int use_stdin;		/* force stdin for passwds */
168     extern char *superfile;		/* The actual superfile to be opened. */
169     extern char superfile_init[];	/* The super.init file. */
170     extern int it_came_from_cmdline;	/* Set by -F/-T/-U/-G flags */
171     extern int using_user_supertab;	/* !0 means using a user's .supertab */
172     extern int error_counter;		/* incremented by Error() */
173 
174 /* The following external variables control the Error() routine.
175  * They are modified at various points by super(), to give detailed control
176  * over the error messages that are printed.
177  */
178     extern int error_stderr;		/* stderr() bool */
179     extern int error_syslog;		/* syslog() bool */
180     extern char *error_rlog_host;	/* where rsyslog() msgs are sent */
181     extern int error_priority;		/* syslog() "priority" */
182     extern int error_facility;		/* openlog() "facility" */
183     extern char *error_command;		/* our program name */
184     extern char *error_user;		/* our caller's username */
185 
186     extern int error_line;		/* input line number of error */
187     extern int error_nl;		/* number of lines this msg refers to */
188     extern char *error_srcfile;		/* filename of input with error */
189 
190 /*
191  * For use with strqtokS -- see that routine for definitions of strqS_xxx
192  */
193     extern unsigned char *strqS_qm;	/* For fast access by strqtokS */
194     extern unsigned char my_qm[256];
195     extern unsigned char *strqS_cc;	/* For fast access by strqtokS */
196     extern unsigned char my_cc[256];
197 
198 
199 /*
200  * Extern variable and routines used to compile/match user/group/host patterns.
201  */
202 extern char *(*pat_compile) P__(( char *));
203 extern int (*pat_compare) P__(( char *));
204 extern int need_re_anchor;
205 /* ========================================================================= */
206 
207 /*
208  * Basic structures from which we construct other, bigger entities.
209  */
210 
211 struct simpleList {
212     char *pat;
213     struct simpleList *next;
214 };
215 typedef struct simpleList SimpleList;
216 
217 struct simple2List {
218     char *pat;
219     struct simpleList *other;
220     struct simple2List *next;
221 };
222 typedef struct simple2List Simple2List;
223 
224 struct timeEnt {
225     short begin;	/* Start time, in minutes */
226     short end;		/* End time, in minutes */
227     char day;		/* day of week to match (0..6); 7 means any day */
228     char invert;	/* match is to be inverted */
229 };
230 typedef struct timeEnt TimeEnt;
231 
232 struct timeList {
233     TimeEnt te;
234     struct timeList *next;
235 };
236 typedef struct timeList TimeList;
237 
238 /* Linked open files */
239 struct fileList {
240     char *givenname;	/* filename, as given in the parent file */
241     char *fullname;	/* filename, fully expanded */
242     FILE *fp;
243     int line;		/* current line */
244     int nl;		/* number of lines in this block */
245     struct fileList *prev;
246 };
247 typedef struct fileList FileList;
248 
249 struct countedString {
250     char *s;		/* malloc'd string */
251     int n;		/* number of characters in s */
252     unsigned char used;	/* !0 means this string is in use */
253 };
254 typedef struct countedString CountedString;
255 
256 struct strArray {
257     CountedString *str;	/* Pts to malloc'd array of CountedString's */
258     int n;		/* number strings allocated */
259 };
260 typedef struct strArray StrArray;
261 
262 struct argRangePat {
263     char *pat;		/* pattern to be matched by ... */
264     int arg1;		/* this arg through... */
265     int arg2;		/* this arg. */
266     struct argRangePat *next;
267 };
268 typedef struct argRangePat ArgRangePat;
269 
270 struct ourTime {
271     time_t start;	/* when program started */
272     short min;		/* local time of day, in minutes */
273     char day;		/* local day, with 0=sunday */
274 };
275 typedef struct ourTime OurTime;
276 
277 struct conditions {
278     int user;		/* !0 -> Last match to a user pattern */
279     int time;		/* !0 -> Matched a time pattern */
280     int allinverted;	/* !0 -> all time patterns scanned were inverted */
281 };
282 typedef struct conditions Conditions;
283 
284 /* The progList struct is for listing all Cmd::File pairs on a control line. */
285 struct progList {
286     char *Cmd;
287     char *File;
288 };
289 typedef struct progList ProgList;
290 
291 /* ========================================================================= */
292 #ifdef HAVE_ENUM
293 extern enum {SUPER_AUTH_PASSWORD, SUPER_AUTH_PAM} Method;
294 #else
295 /* No enums! */
296 #define SUPER_AUTH_PASSWORD 1
297 #define SUPER_AUTH_PAM 2
298 #endif
299 
300 /* Authentication information */
301 struct authInfo {
302     int required;	/* 0 = no auth required */
303     int method;		/* AUTH_PASSWD, AUTH_PAM, etc */
304     int timeout;	/* Time before re-authentication required */
305     int renewtime;	/* update the timestamp file with each use of cmd? */
306     int perhost;	/* create timestamp files separately for each host? */
307     char user[1024];	/* value of authuser=xxx, if entered */
308     char ts_user[1024];	/* value of timestampuid=xxx, if entered */
309     char *prompt;	/* optional string with which to prompt for authinfo */
310 };
311 typedef struct authInfo AuthInfo;
312 
313 /* Information for logging use */
314 struct logInfo {
315     FILE *fp;			/* logfile pointer */
316     char filename[1024];	/* logfile name */
317     char user[1024];		/* value of loguid=xxx, if entered */
318     uid_t uid;			/* UID under which we open logfile */
319     pid_t pid;			/* PID of the logger; -1 means none running. */
320     unsigned char newfile;	/* Bool: !0 if logfile given but not yet used */
321     unsigned char newuid;	/* Bool: !0 if loguid given, but not yet used */
322     int syslog_success;		/* syslog() "priority" for success msgs */
323 };
324 typedef struct logInfo LogInfo;
325 
326 /* progMatch is for keeping track of matches in a ProgList */
327 struct progMatch {
328     ProgList *cmd_file;
329     int match;	/* index in proglist of matched command; -1 if no match */
330     int evermatched;	/* 0 if no cmd in file matched pat */
331     char *commandfound;	/* If match >= 0, commandfound points to actual
332 			 * command matched.  This can differ from
333 			 * proglist.Cmd[match], because that Cmd can be
334 			 * a pattern.
335 			 */
336     int n;
337     int nalloc;
338 };
339 typedef struct progMatch ProgMatch;
340 
341 /* ========================================================================= */
342 
343 /*
344  * Global information from the :global lines
345  */
346 struct globalInfo {
347     char owner[32];	/* Owner of FullPath must be this person; overridden
348 			 * by local owner=xxx option, if present.
349 			 */
350     char *chdir_path;	/* Change to this dir before exec'ing; null if none */
351     int relative_path;	/* Allow filenames to be relative.  This is
352 			 * in general a stupid idea.  Don't do it!
353 			 */
354     int group_slash;	/* Allow group names to have slashes.  If you
355 			 * allow this, you make it harder to catch certain
356 			 * command-line typos.  Don't do it!
357 			 */
358     int maxenvlen;	/* max length of envvar (all of "name=value") */
359     char **env;		/* null-terminated list of vars from env=var[,...] */
360 
361     int nice_incr;	/* value of the nice=nnn increment value */
362 
363     int mask;		/* umask setting */
364 
365     long maxlen1arg;	/* max len of any single arg */
366     long maxlenargs;	/* max len of all args, combined */
367     int usr_args[2];	/* number of user-entered args allowed */
368     ArgRangePat argpats;	/* arg[MMM-]NNN=xxx arguments */
369 
370     AuthInfo authinfo;	/* authentication information */
371 
372     Simple2List userbefore;	/* list of u/g/h pats before per-cmd pats */
373     Simple2List userafter;	/* list of u/g/h pats after per-cmd pats */
374     SimpleList b_a_text;	/* list of original text for above */
375     int user_clear;		/* clear userbefore list if new val seen */
376 
377     TimeList timebefore;	/* A list of the actual time ranges used */
378     TimeList timeafter;		/* A list of the actual time ranges used */
379     int time_clear;		/* clear timebefore list if new val seen */
380 
381     int use_after;		/* !set to !0 when we see <> */
382 
383     LogInfo log;		/* Information for logging to file */
384 
385     char mailcmd[500];		/* Information for logging via mail */
386     int mail_success;		/* bool: mail on success? (-1 = unknown) */
387     int gethostbyname;		/* bool: use gethostbyname()? */
388 
389     GETGROUPS_T groups[NGROUPS_MAX];	/* groups from [add]groups=xxx,... */
390     int ngroups;		/* number of supplementary groups */
391     int groups_added;		/* bool: groups were addgroups=, not groups= */
392 
393     char *setenv[MAXSETENV+1];	/* values of setenv=var[,...] option */
394 };
395 typedef struct globalInfo GlobalInfo;
396 
397 /*
398  * Information describing the caller
399  */
400 struct userInfo {
401     struct passwd caller;		/* who's invoking program */
402     char hostname[MAXHOSTNAMELEN];	/* whence came the user */
403     char lc_hostname[MAXHOSTNAMELEN];	/* hostname in lower case */
404     int orig_mask;			/* umask setting at startup */
405 
406     uid_t orig_uid;			/* uid at prog start, from getuid() */
407     gid_t orig_gid;			/* gid at prog start, from getgid() */
408     uid_t new_uid;			/* new uid, from uid=xxx or u+g=xxx */
409     gid_t new_gid;			/* new gid, from gid=xxx or u+g=xxx */
410     uid_t new_euid;			/* new euid, from uid=xxx or euid=xxx */
411     gid_t new_egid;			/* new egid, from gid=xxx or egid=xxx */
412 
413     OurTime ourtime;			/* when we started, etc */
414 
415     char encr[1000];			/* encrypted password; length is */
416 					/* pretty large by current standards */
417     char salt[1000];			/* salt from password */
418 };
419 typedef struct userInfo UserInfo;
420 
421 /*
422  * Per-entry (in the super.tab file) information.  This gets filled in
423  * at various points, as the program learns more.
424  */
425 struct localInfo {
426     ProgMatch progs;	/* Records prog::file sets, and is updated w/ matches */
427 
428     char *info;		/* value of info=xxx option */
429     char *die;		/* Gets msg from die=msg ; null if none */
430     char *print;	/* Gets msg from print=msg ; null if none */
431     char *chdir_path;	/* Change to this dir before exec'ing; null if none */
432     char *argv0;	/* value of argv0=xxx option */
433 
434     char user[32];	/* value of uid=xxx options */
435     char euser[32];	/* value of euid=xxx options */
436     char group[32];	/* value of group=xxx options */
437     char egroup[32];	/* value of egroup=xxx options */
438     char u_g[32];	/* value of u+g=xxx option */
439     char owner[32];	/* value of owner=xxx option */
440     uid_t file_uid;	/* uid of the matched FullPath */
441     gid_t file_gid;	/* gid of the matched FullPath */
442     GETGROUPS_T groups[NGROUPS_MAX];	/* groups from [add]groups=xxx,... */
443     int ngroups;	/* number of supplementary groups */
444     int groups_added;	/* bool: groups were addgroups=, not groups= */
445     int maxenvlen;	/* max length of envvar (all of "name=value") */
446     char **env;		/* null-terminated list of vars from env=var[,...] */
447     char *setenv[MAXSETENV+1];	/* values of setenv=var[,...] option */
448     char *fdlist;	/* value of fd=nnn[,...] option */
449     int mask;		/* value of umask=xxx option */
450     int nice_incr;	/* value of the nice=nnn increment value */
451     Simple2List userpats;	/* list of PermittedUser patterns */
452     SimpleList origtext;	/* list of PermittedUser patterns */
453     TimeList time;	/* A list of the actual time ranges used */
454     int usr_args[2];	/* number of user-entered args allowed */
455     long maxlen1arg;	/* max len of any single arg */
456     long maxlenargs;	/* max len of all args, combined */
457     ArgRangePat argpats;	/* arg[MMM-]NNN=xxx arguments */
458     char **checkvar;	/* null-term'd list of vars from checkvar=var[,...] */
459 
460     char mailcmd[500];	/* Information for logging via mail */
461     int mail_success;	/* bool: mail on successful tries? (-1 = unknown) */
462 
463     int *fd;		/* descriptors from fdlist string */
464     AuthInfo authinfo;	/* authentication requirements on this command */
465 };
466 typedef struct localInfo LocalInfo;
467 
468 /* ========================================================================= */
469 
470 extern FileList *currfile;		/* list of currently-open files */
471 
472 extern char authInitMsg1[];		/* msg from authentication init */
473 extern char authInitMsg2[];		/* suppl msg from authentication init */
474 extern int authInitErrno;		/* errno, if relevant, to go
475 					 * with authInitMsg1 */
476 
477 extern GlobalInfo globalinfo;		/* :global info */
478 
479 extern UserInfo userinfo;		/* User's info */
480 
481 extern LocalInfo localinfo;		/* per-cmd info */
482 
483 extern Conditions matches;		/* To keep track of what matched */
484 
485 /* ========================================================================= */
486 void	 ARfree P__((ArgRangePat *head));
487 int	ARinsert P__((ArgRangePat *start, int arg1, int arg2, char *pat));
488 ArgRangePat *
489 	ARnext P__((ArgRangePat *start, int iarg));
490 void	add_builtin_variables P__(( void ));
491 #ifdef HAVE_SYSINFO
492 int	add_sysinfo_variables P__(( void ));
493 #endif
494 #ifdef HAVE_UNAME
495 int	add_uname_variables P__(( void ));
496 #endif
497 int	add_variable P__(( char *varname, char *vardefn ));
498 void	anchor P__(( char *in, char *out ));
499 char*	approve P__((char *usrcmd, int givehelp, int verbose));
500 char*	auth_name P__(( void ));
501 int	balancedbraces P__(( char *s ));
502 char ** blkdup P__((char **blk));
503 int	blkfree P__((char **av0));
504 char ** Blkdup P__((char *str, char **blk));
505 int	Blkfree P__((char *str, char **av0));
506 int	blkprint P__((char **));
507 int	build_cmd_file P__((char *, int , char *, char **));
508 char**	buttonup P__((char *));
509 int	canonicalize_hostname P__(( char *buf, int len));
510 int	check_arglistlen P__(( char **argv ));
511 int	check_auth P__(( char *cmd ));
512 int	check_owner P__(( void ));
513 int	check_rpath P__((char *r_path, char *path));
514 void	check_stdio P__((void));
515 int	check_value P__(( char *value, char *pat ));
516 int	check_var_value P__(( void ));
517 int	checkarg P__(( char *str ));
518 int	checkenv P__(( char *name,  char *value,  char *pat ));
519 char*	clean_buf P__(( char *buf, char *outbuf ));
520 void	close_writer P__(( void ));
521 int	colon_define P__(( char *command ));
522 int	colon_die P__(( char *command ));
523 int	colon_getenv P__(( char *command ));
524 int	colon_global P__(( char *command ));
525 int	colon_include P__(( char *command, int allow_missing ));
526 int	colon_if P__(( char *command, int *colonif_succeeded ));
527 int	conditions_and_options P__(( char *cond_or_opt_wd ));
528 struct passwd *
529 	construct_user_superfile P__(( char *user ));
530 char*	dayname P__(( int daynum ));
531 int	daynum P__(( int unixtime ));
532 void	debug_print P__((char *path, char **arglist, char **envp, int n_bltin));
533 void	debug_hello P__((void));
534 int	do_options P__((int argc, char **argv, int *help, int *vers,
535 		    int *verbose, int *printvars,
536 		    char **owned_by_file, char **required_path));
537 char*	do_variables P__(( char *str));
538 char*	docrypt P__((char *key, char *salt));
539 char*	ends P__(( char *s1, char *s2 ));
540 #ifdef HAVE_STDARG_H
541 #ifdef HAVE___ATTRIBUTE__
542 int     Error P__(( int show_perror, int die, char * fmt, ... )) __attribute__ ((format (printf, 3, 4)));
543 #else
544 int	Error P__(( int show_perror, int die, char * fmt, ... ));
545 #endif
546 
547 #else
548 int	Error();
549 #endif
550 FileList* file_open P__(( FileList *list, char *name,
551 			int allow_missing, uid_t *req_uid, gid_t *req_gid ));
552 FileList* file_close P__(( FileList *list ));
553 char*	fillbuffer P__(( FILE *fp, int *indentok, int *nl ));
554 int	findgid P__(( int allowbrackets, char *grouplabel ));
555 int	findgroup P__(( char *grouplabel ));
556 int	fixup_fullpath P__((int , char *, char *, char *, int ));
557 void	free_SimpleList P__(( SimpleList *));
558 void	free_Simple2List P__(( Simple2List *));
559 void	free_TimeList P__(( TimeList *));
560 int	get_canonical_hostname P__((char *buf, int len));
561 int	get_encrypted_pw P__(( void ));
562 int	get_owner P__((char *path, uid_t *uid, gid_t *gid));
563 int	get_pam P__(( char *cmd, char *caller, char *user ));
564 int	get_password P__(( char *cmd, char *caller, char *user,
565 			char *salt,  char *encr ));
566 char*	get_variable P__(( char *varname ));
567 char*	Getenv P__(( char *s ));
568 int	Getgroups P__((int, GETGROUPS_T *));
569 struct group *
570 	getgrentry P__(( char *name ));
571 int	getlogdir P__((char *user, char *buf));
572 struct passwd *
573 	getpwentry P__((int allow_brackets, char *username));
574 int	global_arg P__((char *word));
575 int	globbraces P__(( char *s, int wrap_in_braces, char ***globlist ));
576 int	handle_option P__((char *word, char *s, int isglobal));
577 int	ingroup P__(( char * user, gid_t gid, char * gp_pat ));
578 void	init_nice_incr P__((int is_global));
579 void	init_strqtokS P__(( void ));
580 void	init_umask P__((int is_global));
581 void	init_globalinfo P__( (void) );
582 void	init_localinfo P__( (void) );
583 int	init_userinfo P__( (void) );
584 int	InsertCondition P__(( char *, char *, int ));
585 int	InsertTimeList P__(( char *, char **, TimeList *, char *, int ));
586 int	InsertUserList P__((char *, char **, Simple2List *, SimpleList *, int));
587 void	logmsg P__(( char * cmd, char ** args ));
588 int	makedir P__(( char *directories, int *err, char *msgbuf ));
589 char*	makedirname P__(( char *prefix, char *hostname, char *path, int *err, char *msgbuf ));
590 int	match_pattern P__((int match, int glob, char *str, char *pattern));
591 void	match_ugh_user P__((Simple2List *sl, int isglobal));
592 void	matchtime P__(( OurTime *our, TimeList *tl ));
593 char**	newargs P__((char *path_plus, char **argv, int *n_builtin));
594 FILE*	open_writer P__(( char *user, char *filename, pid_t *pid_p ));
595 void	opensuperlog P__(( void ));
596 int	option_clear_settings P__((char *word, char *s, int isglobal));
597 int	option_global_reset_settings P__((void));
598 int	option_local_clear_settings P__((void));
599 void	p_regcomp_flags P__(( int ));
600 char*	p_compile P__(( char *));
601 int	p_compare P__(( char *));
602 int	parseline P__((int givehelp, int checksyntax, char *buf, char *usrcmd));
603 void	print_variable P__(( int indx, char *key, char *data ));
604 void	printhelp P__(( int verbose ));
605 void	printhelp_hello P__(( int verbose, char *usrcmd ));
606 int	process_colon_cmds P__(( char *command, int *colonif_succeeded ));
607 int	process_logfile_opt P__(( void ));
608 int	rcl_nice_incr P__((void));
609 int	rcl_umask P__((void));
610 void	re_anchor P__(( char *in, char *out));
611 int	s_getpass P__((char *prompt, int use_stdin, char *buf, int buflen));
612 char*	s_re_comp P__(( char *));
613 int	s_re_exec P__(( char *));
614 void	readtime_init P__(( void ));
615 int	readtimerange P__(( char *str, short *t1, short *t2, char *d ));
616 int	readtime P__(( char *str, short *t1, char *d ));
617 int	save_var_value P__((char *var_value));
618 int	set_chdir P__((void));
619 int	set_nice_incr P__((void));
620 int	set_u_g P__(( void ));
621 void	set_umask P__((void));
622 int	Setgroups P__((int, GETGROUPS_T *));
623 int	shell_compare P__(( char *));
624 char*	shell_compile P__(( char *));
625 void	store_nice_incr P__((int nice_incr, int is_global));
626 void	store_umask P__((int mask, int is_global));
627 char*	str_val P__(( char *left, int sep, char *str ));
628 int	StrBulkCpy P__(( StrArray *dst, int dst_ielt, StrArray *src, int src_ielt, int nelt ));
629 int	StrEltCpy P__(( StrArray *a, int ielt, char *str));
630 char*	StrEltGetPtr P__(( StrArray *a, int ielt ));
631 void	StrEltsUnused P__(( StrArray *a ));
632 void	StrInit P__(( StrArray *a ));
633 int	stringcopy P__(( char *to, char *from, int n));
634 int	StrLastInUse P__(( StrArray *a ));
635 int	StrNalloc P__(( StrArray *a, int nelt));
636 int	StrNelts P__(( StrArray *a ));
637 void	strtolower P__(( char *string ));
638 char*	strqtokS P__(( char *, char *, char *, char *, unsigned int ));
639 int	read_syslogcode P__(( char *str, int *code ));
640 void	user_supertab P__(( char *file_or_user, int is_file, char *cmd ));
641 int	wildmat P__(( char *text, char *p ));
642