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