1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 1995 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland 28*5c51f124SMoriah Waterland /* 29*5c51f124SMoriah Waterland * The purpose of this lex specification is to estimate the 30*5c51f124SMoriah Waterland * correctness of the various scripts that accompany packages. It 31*5c51f124SMoriah Waterland * is not flawless, but it is a better review than that of prior 32*5c51f124SMoriah Waterland * package validators. It looks for indications of interaction, 33*5c51f124SMoriah Waterland * root calls and attempts to modify locked files. 34*5c51f124SMoriah Waterland */ 35*5c51f124SMoriah Waterland %e 1500 36*5c51f124SMoriah Waterland %p 3500 37*5c51f124SMoriah Waterland %s WHROOT 38*5c51f124SMoriah Waterland %{ 39*5c51f124SMoriah Waterland #undef input 40*5c51f124SMoriah Waterland #undef unput 41*5c51f124SMoriah Waterland FILE *scr_fp; 42*5c51f124SMoriah Waterland #define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(scr_fp))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) 43*5c51f124SMoriah Waterland #define unput(p) ungetc(p, scr_fp) 44*5c51f124SMoriah Waterland 45*5c51f124SMoriah Waterland #define INTERACT_D 0x00000001 /* definitely */ 46*5c51f124SMoriah Waterland #define ROOT_D 0x00000002 47*5c51f124SMoriah Waterland #define LOCKED_D 0x00000004 48*5c51f124SMoriah Waterland #define INTERACT_M 0x00010000 /* might be true, or we ... */ 49*5c51f124SMoriah Waterland #define ROOT_M 0x00020000 /* ... might be reading it wrong. */ 50*5c51f124SMoriah Waterland #define LOCKED_M 0x00040000 51*5c51f124SMoriah Waterland #define WPARM1_M 0x00080000 /* attempt to write to $1 */ 52*5c51f124SMoriah Waterland #define USEPARM1_M 0x00100000 /* other attempt to use $1 */ 53*5c51f124SMoriah Waterland #define ODDPARM_M 0x00200000 /* use of some other parameter */ 54*5c51f124SMoriah Waterland #define PKGDB_M 0x00400000 /* read access to DB */ 55*5c51f124SMoriah Waterland #define INITVAL 0x40000000 56*5c51f124SMoriah Waterland 57*5c51f124SMoriah Waterland /* Abbreviations */ 58*5c51f124SMoriah Waterland #define INTERACT (INTERACT_D | INTERACT_M) 59*5c51f124SMoriah Waterland #define ROOT (ROOT_D | ROOT_M) 60*5c51f124SMoriah Waterland #define LOCKED (LOCKED_D | LOCKED_M) 61*5c51f124SMoriah Waterland #define HASPARM (WPARM1_M | USEPARM1_M | ODDPARM_M) 62*5c51f124SMoriah Waterland 63*5c51f124SMoriah Waterland /* Things the preinstall and preremove scripts can't do. */ 64*5c51f124SMoriah Waterland #define PRE_MASK (INTERACT | LOCKED | PKGDB_M | HASPARM) 65*5c51f124SMoriah Waterland /* 66*5c51f124SMoriah Waterland * Things the class action script can't do. Don't get the impression that 67*5c51f124SMoriah Waterland * this means the class action script can be interactive; but, it can 68*5c51f124SMoriah Waterland * legitimately read stdin (which is what INTERACT tests for). 69*5c51f124SMoriah Waterland */ 70*5c51f124SMoriah Waterland #define CAS_MASK (LOCKED | PKGDB_M | WPARM1_M | ODDPARM_M) 71*5c51f124SMoriah Waterland /* Things the postinstall and postremove scripts can't do. */ 72*5c51f124SMoriah Waterland #define POST_MASK (INTERACT | HASPARM) 73*5c51f124SMoriah Waterland /* Things the request script can't do. */ 74*5c51f124SMoriah Waterland #define REQ_MASK (ROOT | ODDPARM_M) 75*5c51f124SMoriah Waterland /* Things the checkinstall script can't do. */ 76*5c51f124SMoriah Waterland #define CHK_MASK (INTERACT | ROOT | ODDPARM_M) 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland /* Nothing definite - not worth returning an error */ 79*5c51f124SMoriah Waterland #define MAYBE_ONLY ~(INTERACT_D | ROOT_D | LOCKED_D) 80*5c51f124SMoriah Waterland 81*5c51f124SMoriah Waterland #define WRN_INST_F "WARNING: script <%s> uses installf but no " \ 82*5c51f124SMoriah Waterland "installf -f was detected." 83*5c51f124SMoriah Waterland #define WRN_REM_F "WARNING: script <%s> uses removef but no " \ 84*5c51f124SMoriah Waterland "removef -f was detected." 85*5c51f124SMoriah Waterland #define WRN_INTERACT "WARNING: script <%s> may require " \ 86*5c51f124SMoriah Waterland "user interaction at line <%d>." 87*5c51f124SMoriah Waterland #define WRN_LOCKED "WARNING: script <%s> may seek access to the " \ 88*5c51f124SMoriah Waterland "transitional package database at line <%d>. " \ 89*5c51f124SMoriah Waterland "This is safest in the postinstall or " \ 90*5c51f124SMoriah Waterland "postremove script." 91*5c51f124SMoriah Waterland #define WRN_ROOT "WARNING: script <%s> may not have permission " \ 92*5c51f124SMoriah Waterland "to execute line <%d>." 93*5c51f124SMoriah Waterland #define WRN_FORM_ARG "WARNING: not sure where script <%s> gets the "\ 94*5c51f124SMoriah Waterland "parameter at line <%d>." 95*5c51f124SMoriah Waterland #define WRN_FORM_USE "WARNING: script <%s> questionable usage of "\ 96*5c51f124SMoriah Waterland "parameter at line <%d>." 97*5c51f124SMoriah Waterland #define WRN_TRANSDB "WARNING: script <%s> questionable read " \ 98*5c51f124SMoriah Waterland "of package database at line <%d>. An " \ 99*5c51f124SMoriah Waterland "intermediate buffer may be appropriate." 100*5c51f124SMoriah Waterland #define WRN_SPACEACC "WARNING: script <%s> updates the package database " \ 101*5c51f124SMoriah Waterland "but provides no space file to account for " \ 102*5c51f124SMoriah Waterland "the additional package object." 103*5c51f124SMoriah Waterland #define ERR_INTERACT "ERROR: script <%s> requires user " \ 104*5c51f124SMoriah Waterland "interaction at line <%d>." 105*5c51f124SMoriah Waterland #define ERR_LOCKED "ERROR: script <%s> attempts to modify locked " \ 106*5c51f124SMoriah Waterland "package database at line <%d>." 107*5c51f124SMoriah Waterland #define ERR_ROOT "ERROR: script <%s> requires root permission at " \ 108*5c51f124SMoriah Waterland "line <%d>." 109*5c51f124SMoriah Waterland #define ERR_FOPEN "ERROR: Cannot evaluate script <%s>, errno=%d." 110*5c51f124SMoriah Waterland #define ERR_ARGS "ERROR: scripteval() - no script provided for " \ 111*5c51f124SMoriah Waterland "evaluation." 112*5c51f124SMoriah Waterland extern int errno; 113*5c51f124SMoriah Waterland 114*5c51f124SMoriah Waterland static int line_no; /* current line number */ 115*5c51f124SMoriah Waterland int pipe_release = 0; /* loop level for release of pipe */ 116*5c51f124SMoriah Waterland int loop_depth = 0; /* current number of nested loops */ 117*5c51f124SMoriah Waterland int case_depth = 0; /* same for case ... */ 118*5c51f124SMoriah Waterland int if_depth = 0; /* ... and if statements */ 119*5c51f124SMoriah Waterland int cur_level = 0; /* current number of nested anything */ 120*5c51f124SMoriah Waterland int braces = 0; /* depth into a function */ 121*5c51f124SMoriah Waterland 122*5c51f124SMoriah Waterland int lock_level = 0; 123*5c51f124SMoriah Waterland int root_level = 0; 124*5c51f124SMoriah Waterland 125*5c51f124SMoriah Waterland struct statstrct { 126*5c51f124SMoriah Waterland unsigned int in_function:1; 127*5c51f124SMoriah Waterland unsigned int in_pipe:1; 128*5c51f124SMoriah Waterland unsigned int in_loop:1; 129*5c51f124SMoriah Waterland unsigned int in_case:1; 130*5c51f124SMoriah Waterland unsigned int in_if:1; 131*5c51f124SMoriah Waterland unsigned int in_awk:1; 132*5c51f124SMoriah Waterland unsigned int allow_int:1; /* Allow an interactive function. */ 133*5c51f124SMoriah Waterland unsigned int pkg_rtn_done:1; 134*5c51f124SMoriah Waterland unsigned int pkgchk_f:1; 135*5c51f124SMoriah Waterland unsigned int instf:1; 136*5c51f124SMoriah Waterland unsigned int instf_f:1; 137*5c51f124SMoriah Waterland unsigned int remf:1; 138*5c51f124SMoriah Waterland unsigned int remf_f:1; 139*5c51f124SMoriah Waterland unsigned int nospacefile:1; 140*5c51f124SMoriah Waterland unsigned int needspacefile:1; 141*5c51f124SMoriah Waterland } status = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 142*5c51f124SMoriah Waterland 143*5c51f124SMoriah Waterland %} 144*5c51f124SMoriah Waterland %% 145*5c51f124SMoriah Waterland %{ 146*5c51f124SMoriah Waterland /* 147*5c51f124SMoriah Waterland * Validate a few OK patterns that look like bad patterns. These include: 148*5c51f124SMoriah Waterland * 1. comments 149*5c51f124SMoriah Waterland * 2. quoted strings 150*5c51f124SMoriah Waterland * 3. writes to $1 (request script) 151*5c51f124SMoriah Waterland * 4. reads from $1 (CAS) 152*5c51f124SMoriah Waterland * 5. writes to /dev/null 153*5c51f124SMoriah Waterland */ 154*5c51f124SMoriah Waterland %} 155*5c51f124SMoriah Waterland #.*$ return INITVAL; 156*5c51f124SMoriah Waterland 157*5c51f124SMoriah Waterland \` unput(' '); /* No executable matching */ 158*5c51f124SMoriah Waterland 159*5c51f124SMoriah Waterland %{ 160*5c51f124SMoriah Waterland /* Anybody can write to /dev/null and anybody can write to /tmp. */ 161*5c51f124SMoriah Waterland %} 162*5c51f124SMoriah Waterland \>[ \t]*"/dev/null" return INITVAL; 163*5c51f124SMoriah Waterland \>[ \t]*"/tmp" return INITVAL; 164*5c51f124SMoriah Waterland 165*5c51f124SMoriah Waterland %{ 166*5c51f124SMoriah Waterland /* If it's escaped, the next entry may as well be a space. */ 167*5c51f124SMoriah Waterland %} 168*5c51f124SMoriah Waterland \\ { 169*5c51f124SMoriah Waterland char ch; 170*5c51f124SMoriah Waterland 171*5c51f124SMoriah Waterland if ((ch = input()) == '\n') 172*5c51f124SMoriah Waterland line_no++; 173*5c51f124SMoriah Waterland 174*5c51f124SMoriah Waterland unput(' '); 175*5c51f124SMoriah Waterland } 176*5c51f124SMoriah Waterland 177*5c51f124SMoriah Waterland %{ 178*5c51f124SMoriah Waterland /* In the quotes is OK. */ 179*5c51f124SMoriah Waterland %} 180*5c51f124SMoriah Waterland \" { 181*5c51f124SMoriah Waterland char ch; 182*5c51f124SMoriah Waterland while ((ch = input()) != '\"') { 183*5c51f124SMoriah Waterland if (ch == '\\') { 184*5c51f124SMoriah Waterland input(); /* Read this into the bit bucket. */ 185*5c51f124SMoriah Waterland continue; 186*5c51f124SMoriah Waterland } 187*5c51f124SMoriah Waterland if (ch == '\n') 188*5c51f124SMoriah Waterland line_no++; 189*5c51f124SMoriah Waterland else if (ch == '\0') 190*5c51f124SMoriah Waterland return (0); /* EOF */ 191*5c51f124SMoriah Waterland } 192*5c51f124SMoriah Waterland } 193*5c51f124SMoriah Waterland 194*5c51f124SMoriah Waterland %{ 195*5c51f124SMoriah Waterland /* In the single quotes is OK if they aren't associated with an awk script. */ 196*5c51f124SMoriah Waterland %} 197*5c51f124SMoriah Waterland \' { 198*5c51f124SMoriah Waterland char ch; 199*5c51f124SMoriah Waterland 200*5c51f124SMoriah Waterland if (status.in_awk != 0) 201*5c51f124SMoriah Waterland REJECT;; 202*5c51f124SMoriah Waterland 203*5c51f124SMoriah Waterland while ((ch = input()) != '\'') { 204*5c51f124SMoriah Waterland if (ch == '\\') { 205*5c51f124SMoriah Waterland input(); /* Read this into the bit bucket. */ 206*5c51f124SMoriah Waterland continue; 207*5c51f124SMoriah Waterland } 208*5c51f124SMoriah Waterland if (ch == '\n') 209*5c51f124SMoriah Waterland line_no++; 210*5c51f124SMoriah Waterland else if (ch == '\0') 211*5c51f124SMoriah Waterland return (0); /* EOF */ 212*5c51f124SMoriah Waterland } 213*5c51f124SMoriah Waterland } 214*5c51f124SMoriah Waterland 215*5c51f124SMoriah Waterland %{ 216*5c51f124SMoriah Waterland /* 217*5c51f124SMoriah Waterland * Check for use of parameters passed to the script. 218*5c51f124SMoriah Waterland * 1. writes to $1 as though it were a file 219*5c51f124SMoriah Waterland * 2. use of $1 in any capacity 220*5c51f124SMoriah Waterland * 3. use of other parameters 221*5c51f124SMoriah Waterland * Within a function or an awk script, these parameters aren't 222*5c51f124SMoriah Waterland * the one's of interest. 223*5c51f124SMoriah Waterland */ 224*5c51f124SMoriah Waterland %} 225*5c51f124SMoriah Waterland \>[\t ]*\$1/[\t\n ] { 226*5c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 227*5c51f124SMoriah Waterland return (WPARM1_M); 228*5c51f124SMoriah Waterland } 229*5c51f124SMoriah Waterland 230*5c51f124SMoriah Waterland ^$1/[\t\n ] | 231*5c51f124SMoriah Waterland [\t ]$1/[\t\n ] { 232*5c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 233*5c51f124SMoriah Waterland return (USEPARM1_M); 234*5c51f124SMoriah Waterland } 235*5c51f124SMoriah Waterland 236*5c51f124SMoriah Waterland \$[2-9] | 237*5c51f124SMoriah Waterland \$[0-9][0-9]+ { 238*5c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 239*5c51f124SMoriah Waterland return (ODDPARM_M); 240*5c51f124SMoriah Waterland } 241*5c51f124SMoriah Waterland 242*5c51f124SMoriah Waterland %{ 243*5c51f124SMoriah Waterland /* 244*5c51f124SMoriah Waterland * Detect shell function. 245*5c51f124SMoriah Waterland */ 246*5c51f124SMoriah Waterland %} 247*5c51f124SMoriah Waterland "()"[ \t]*\n[ \t]*/\{ { status.in_function = 1; line_no++; } 248*5c51f124SMoriah Waterland "()"[ ]*/\{ status.in_function = 1; 249*5c51f124SMoriah Waterland 250*5c51f124SMoriah Waterland "{" { 251*5c51f124SMoriah Waterland if (status.in_function == 1) 252*5c51f124SMoriah Waterland braces++; 253*5c51f124SMoriah Waterland } 254*5c51f124SMoriah Waterland 255*5c51f124SMoriah Waterland "}" { 256*5c51f124SMoriah Waterland if (status.in_function == 1) { 257*5c51f124SMoriah Waterland braces--; 258*5c51f124SMoriah Waterland if (braces == 0) 259*5c51f124SMoriah Waterland status.in_function = 0; 260*5c51f124SMoriah Waterland } 261*5c51f124SMoriah Waterland } 262*5c51f124SMoriah Waterland 263*5c51f124SMoriah Waterland %{ 264*5c51f124SMoriah Waterland /* 265*5c51f124SMoriah Waterland * Detect for or while loop. 266*5c51f124SMoriah Waterland */ 267*5c51f124SMoriah Waterland %} 268*5c51f124SMoriah Waterland ^for/[\t\n ] | 269*5c51f124SMoriah Waterland [\t ]for/[\t\n ] | 270*5c51f124SMoriah Waterland ^while/[\t\n ] | 271*5c51f124SMoriah Waterland [\t ]while/[\t\n ] { 272*5c51f124SMoriah Waterland status.in_loop = 1; 273*5c51f124SMoriah Waterland loop_depth++; 274*5c51f124SMoriah Waterland cur_level++; 275*5c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 276*5c51f124SMoriah Waterland } 277*5c51f124SMoriah Waterland 278*5c51f124SMoriah Waterland ^done/[\t\n ] | 279*5c51f124SMoriah Waterland [\t ]done/[\t\n ] { 280*5c51f124SMoriah Waterland if (status.in_loop == 1) 281*5c51f124SMoriah Waterland loop_depth--; 282*5c51f124SMoriah Waterland cur_level--; 283*5c51f124SMoriah Waterland if (loop_depth == 0) 284*5c51f124SMoriah Waterland status.in_loop = 0; 285*5c51f124SMoriah Waterland } 286*5c51f124SMoriah Waterland 287*5c51f124SMoriah Waterland %{ 288*5c51f124SMoriah Waterland /* 289*5c51f124SMoriah Waterland * Detect case. 290*5c51f124SMoriah Waterland */ 291*5c51f124SMoriah Waterland %} 292*5c51f124SMoriah Waterland ^case/[\t\n ] | 293*5c51f124SMoriah Waterland [\t ]case/[\t\n ] { 294*5c51f124SMoriah Waterland status.in_case = 1; 295*5c51f124SMoriah Waterland case_depth++; 296*5c51f124SMoriah Waterland cur_level++; 297*5c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 298*5c51f124SMoriah Waterland } 299*5c51f124SMoriah Waterland 300*5c51f124SMoriah Waterland ^esac/[\t\n ] | 301*5c51f124SMoriah Waterland [\t ]esac/[\t\n ] { 302*5c51f124SMoriah Waterland if (status.in_case == 1) 303*5c51f124SMoriah Waterland case_depth--; 304*5c51f124SMoriah Waterland cur_level--; 305*5c51f124SMoriah Waterland if (case_depth == 0) 306*5c51f124SMoriah Waterland status.in_case = 0; 307*5c51f124SMoriah Waterland } 308*5c51f124SMoriah Waterland 309*5c51f124SMoriah Waterland %{ 310*5c51f124SMoriah Waterland /* 311*5c51f124SMoriah Waterland * Detect if. 312*5c51f124SMoriah Waterland */ 313*5c51f124SMoriah Waterland %} 314*5c51f124SMoriah Waterland ^if" "*"[" | 315*5c51f124SMoriah Waterland [\t ]if" "*"[" { 316*5c51f124SMoriah Waterland status.in_if = 1; 317*5c51f124SMoriah Waterland if_depth++; 318*5c51f124SMoriah Waterland cur_level++; 319*5c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 320*5c51f124SMoriah Waterland } 321*5c51f124SMoriah Waterland 322*5c51f124SMoriah Waterland ^fi/[\t\n ] | 323*5c51f124SMoriah Waterland [\t ]fi/[\t\n ] { 324*5c51f124SMoriah Waterland if (status.in_if == 1) 325*5c51f124SMoriah Waterland if_depth--; 326*5c51f124SMoriah Waterland cur_level--; 327*5c51f124SMoriah Waterland if (if_depth == 0) 328*5c51f124SMoriah Waterland status.in_if = 0; 329*5c51f124SMoriah Waterland } 330*5c51f124SMoriah Waterland 331*5c51f124SMoriah Waterland %{ 332*5c51f124SMoriah Waterland /* 333*5c51f124SMoriah Waterland * Detect awk or nawk function. If the function is enclosed in "`"s 334*5c51f124SMoriah Waterland * the entire line will be grabbed., so we check for that possibility. 335*5c51f124SMoriah Waterland */ 336*5c51f124SMoriah Waterland %} 337*5c51f124SMoriah Waterland ^n?awk[^\n^']*\' | 338*5c51f124SMoriah Waterland [\t \\\(\/]n?awk[^\n^']*\' status.in_awk = 1; 339*5c51f124SMoriah Waterland 340*5c51f124SMoriah Waterland 341*5c51f124SMoriah Waterland \' { 342*5c51f124SMoriah Waterland if (status.in_awk == 1) 343*5c51f124SMoriah Waterland status.in_awk = 0; 344*5c51f124SMoriah Waterland } 345*5c51f124SMoriah Waterland 346*5c51f124SMoriah Waterland %{ 347*5c51f124SMoriah Waterland /* Detect pipe target. */ 348*5c51f124SMoriah Waterland %} 349*5c51f124SMoriah Waterland [\$A-Za-z] { 350*5c51f124SMoriah Waterland if (status.in_pipe == 1 && pipe_release == cur_level) 351*5c51f124SMoriah Waterland { 352*5c51f124SMoriah Waterland status.in_pipe = 0; /* target located */ 353*5c51f124SMoriah Waterland pipe_release = 0; 354*5c51f124SMoriah Waterland status.allow_int = 1; /* this isn't really interactive. */ 355*5c51f124SMoriah Waterland REJECT; /* put it back */ 356*5c51f124SMoriah Waterland } 357*5c51f124SMoriah Waterland } 358*5c51f124SMoriah Waterland 359*5c51f124SMoriah Waterland %{ 360*5c51f124SMoriah Waterland /* If it's a pipe, note that and continue. */ 361*5c51f124SMoriah Waterland %} 362*5c51f124SMoriah Waterland "||" | 363*5c51f124SMoriah Waterland "|" { 364*5c51f124SMoriah Waterland if (status.in_pipe == 0) { 365*5c51f124SMoriah Waterland status.in_pipe = 1; 366*5c51f124SMoriah Waterland pipe_release = cur_level; 367*5c51f124SMoriah Waterland } 368*5c51f124SMoriah Waterland } 369*5c51f124SMoriah Waterland 370*5c51f124SMoriah Waterland %{ 371*5c51f124SMoriah Waterland /* 372*5c51f124SMoriah Waterland * Test input for admin-type telltale interactive functions. Definite's 373*5c51f124SMoriah Waterland * first, maybe's next. 374*5c51f124SMoriah Waterland */ 375*5c51f124SMoriah Waterland %} 376*5c51f124SMoriah Waterland ^ckdate/[\t\n ] | 377*5c51f124SMoriah Waterland [\t \/]ckdate/[\t\n ] | 378*5c51f124SMoriah Waterland ^ckint/[\t\n ] | 379*5c51f124SMoriah Waterland [\t \/]ckint/[\t\n ] | 380*5c51f124SMoriah Waterland ^ckrange/[\t\n ] | 381*5c51f124SMoriah Waterland [\t \/]ckrange/[\t\n ] | 382*5c51f124SMoriah Waterland ^cktime/[\t\n ] | 383*5c51f124SMoriah Waterland [\t \/]cktime/[\t\n ] | 384*5c51f124SMoriah Waterland ^ckyorn/[\t\n ] | 385*5c51f124SMoriah Waterland [\t \/]ckyorn/[\t\n ] | 386*5c51f124SMoriah Waterland ^ckgid/[\t\n ] | 387*5c51f124SMoriah Waterland [\t \/]ckgid/[\t\n ] | 388*5c51f124SMoriah Waterland ^ckpath/[\t\n ] | 389*5c51f124SMoriah Waterland [\t \/]ckpath/[\t\n ] | 390*5c51f124SMoriah Waterland ^ckstr/[\t\n ] | 391*5c51f124SMoriah Waterland [\t \/]ckstr/[\t\n ] | 392*5c51f124SMoriah Waterland ^ckuid/[\t\n ] | 393*5c51f124SMoriah Waterland [\t \/]ckuid/[\t\n ] { 394*5c51f124SMoriah Waterland if (status.in_pipe == 1 || status.allow_int == 1) 395*5c51f124SMoriah Waterland return (INITVAL); 396*5c51f124SMoriah Waterland else 397*5c51f124SMoriah Waterland return (INTERACT_M); /* maybe should be _D */ 398*5c51f124SMoriah Waterland } 399*5c51f124SMoriah Waterland 400*5c51f124SMoriah Waterland ^read/[\t\n ] | 401*5c51f124SMoriah Waterland [\t ]read/[\t\n ] | 402*5c51f124SMoriah Waterland "=[ ]+&<"[\t ] { 403*5c51f124SMoriah Waterland if (status.in_pipe == 1 || status.allow_int == 1) 404*5c51f124SMoriah Waterland return (INITVAL); 405*5c51f124SMoriah Waterland else 406*5c51f124SMoriah Waterland return (INTERACT_M); 407*5c51f124SMoriah Waterland } 408*5c51f124SMoriah Waterland 409*5c51f124SMoriah Waterland %{ 410*5c51f124SMoriah Waterland /* Scan for root authority commands. Definite's first, maybe's next. */ 411*5c51f124SMoriah Waterland %} 412*5c51f124SMoriah Waterland ^mkdir/[\t\n ] | 413*5c51f124SMoriah Waterland [\t \/]mkdir/[\t\n ] | 414*5c51f124SMoriah Waterland ^mv/[\t\n ] | 415*5c51f124SMoriah Waterland [\t \/]mv/[\t\n ] | 416*5c51f124SMoriah Waterland ^cpio/[\t\n ] | 417*5c51f124SMoriah Waterland [\t \/]cpio/[\t\n ] | 418*5c51f124SMoriah Waterland ^tar/[\t\n ] | 419*5c51f124SMoriah Waterland [\t \/]tar/[\t\n ] | 420*5c51f124SMoriah Waterland ^(un)?compress/[\t\n ] | 421*5c51f124SMoriah Waterland [\t \/](un)?compress/[\t\n ] | 422*5c51f124SMoriah Waterland ^rmdir/[\t\n ] | 423*5c51f124SMoriah Waterland [\t \/]rmdir/[\t\n ] return (ROOT_D); 424*5c51f124SMoriah Waterland 425*5c51f124SMoriah Waterland ^r?cp(dir)?/[\t\n ] | 426*5c51f124SMoriah Waterland [\t \/]r?cp(dir)?/[\t\n ] | 427*5c51f124SMoriah Waterland ^rm/[\t\n ] | 428*5c51f124SMoriah Waterland [\t \/]rm/[\t\n ] | 429*5c51f124SMoriah Waterland \>[ \t]*[\$\/a-zA-Z0-9] return (ROOT_M); 430*5c51f124SMoriah Waterland 431*5c51f124SMoriah Waterland %{ 432*5c51f124SMoriah Waterland /* These root commands may also be locked. */ 433*5c51f124SMoriah Waterland 434*5c51f124SMoriah Waterland /* Here we analyze any pkgchk calls. If it's "pkgchk ... -f ..." then that calls for root authority. We then check for a "-R" argument. */ 435*5c51f124SMoriah Waterland %} 436*5c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-f" | 437*5c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-f" { 438*5c51f124SMoriah Waterland status.pkgchk_f = 1; 439*5c51f124SMoriah Waterland REJECT; /* We need the intermediate args. */ 440*5c51f124SMoriah Waterland } 441*5c51f124SMoriah Waterland 442*5c51f124SMoriah Waterland %{ 443*5c51f124SMoriah Waterland /* If it's "pkgchk ... -R ..." then the local package database is not being tested and no database warning is necessary. */ 444*5c51f124SMoriah Waterland %} 445*5c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n] | 446*5c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n] { 447*5c51f124SMoriah Waterland if (status.pkgchk_f) 448*5c51f124SMoriah Waterland return (ROOT_D); 449*5c51f124SMoriah Waterland else 450*5c51f124SMoriah Waterland return (INITVAL); 451*5c51f124SMoriah Waterland } 452*5c51f124SMoriah Waterland 453*5c51f124SMoriah Waterland %{ 454*5c51f124SMoriah Waterland /* If it's just "pkgchk ..." then we need to mention something about access to the package database. With Solaris 2.5, an improved locking mechanism is in place, so this message may be something we can drop later. */ 455*5c51f124SMoriah Waterland %} 456*5c51f124SMoriah Waterland ^pkgchk/[\t\n ] | 457*5c51f124SMoriah Waterland [\t \/]pkgchk/[\t\n ] { 458*5c51f124SMoriah Waterland if (status.pkgchk_f) { 459*5c51f124SMoriah Waterland status.pkgchk_f = 0; 460*5c51f124SMoriah Waterland return (ROOT_D | PKGDB_M); 461*5c51f124SMoriah Waterland } else 462*5c51f124SMoriah Waterland return (PKGDB_M); 463*5c51f124SMoriah Waterland } 464*5c51f124SMoriah Waterland 465*5c51f124SMoriah Waterland %{ 466*5c51f124SMoriah Waterland /* The installf and removef utilities require root authority, they modify the package database and they must be invoked at least once with a "-f" argument. */ 467*5c51f124SMoriah Waterland 468*5c51f124SMoriah Waterland /* First test for a "-f" argument. */ 469*5c51f124SMoriah Waterland %} 470*5c51f124SMoriah Waterland ^installf[^\n^|^>^;]*"-f" | 471*5c51f124SMoriah Waterland [\t \/]installf[^\n^|^>^;]*"-f" { 472*5c51f124SMoriah Waterland status.instf_f = 1; 473*5c51f124SMoriah Waterland 474*5c51f124SMoriah Waterland REJECT; /* The whole line needs to be re-reviewed. */ 475*5c51f124SMoriah Waterland } 476*5c51f124SMoriah Waterland 477*5c51f124SMoriah Waterland ^removef[^\n^|^>^;]*"-f" | 478*5c51f124SMoriah Waterland [\t \/]removef[^\n^|^>^;]*"-f" { 479*5c51f124SMoriah Waterland status.remf_f = 1; 480*5c51f124SMoriah Waterland 481*5c51f124SMoriah Waterland REJECT; /* The whole line needs to be re-reviewed. */ 482*5c51f124SMoriah Waterland } 483*5c51f124SMoriah Waterland 484*5c51f124SMoriah Waterland ^installf/[\t\n ] | 485*5c51f124SMoriah Waterland [\t \/]installf/[\t\n ] { 486*5c51f124SMoriah Waterland status.instf = 1; 487*5c51f124SMoriah Waterland status.needspacefile = 1; 488*5c51f124SMoriah Waterland 489*5c51f124SMoriah Waterland root_level = ROOT_D; 490*5c51f124SMoriah Waterland lock_level = LOCKED_M; 491*5c51f124SMoriah Waterland 492*5c51f124SMoriah Waterland BEGIN WHROOT; 493*5c51f124SMoriah Waterland } 494*5c51f124SMoriah Waterland 495*5c51f124SMoriah Waterland ^removef/[\t\n ] | 496*5c51f124SMoriah Waterland [\t \/]removef/[\t\n ] { 497*5c51f124SMoriah Waterland status.remf = 1; 498*5c51f124SMoriah Waterland 499*5c51f124SMoriah Waterland root_level = ROOT_D; 500*5c51f124SMoriah Waterland lock_level = LOCKED_M; 501*5c51f124SMoriah Waterland BEGIN WHROOT; 502*5c51f124SMoriah Waterland } 503*5c51f124SMoriah Waterland 504*5c51f124SMoriah Waterland %{ 505*5c51f124SMoriah Waterland /* There's no question that use of a pkgadd or pkgrm in a script is bound to cause problems unless it is to a different root. */ 506*5c51f124SMoriah Waterland %} 507*5c51f124SMoriah Waterland ^pkgadd/[\t\n ] | 508*5c51f124SMoriah Waterland [\t \/]pkgadd/[\t\n ] | 509*5c51f124SMoriah Waterland ^pkgrm/[\t\n ] | 510*5c51f124SMoriah Waterland [\t \/]pkgrm/[\t\n ] { 511*5c51f124SMoriah Waterland root_level = ROOT_D; 512*5c51f124SMoriah Waterland lock_level = LOCKED_D; 513*5c51f124SMoriah Waterland BEGIN WHROOT; 514*5c51f124SMoriah Waterland } 515*5c51f124SMoriah Waterland 516*5c51f124SMoriah Waterland %{ 517*5c51f124SMoriah Waterland /* The only way to get here is if we are in the middle of a pkg command. */ 518*5c51f124SMoriah Waterland %} 519*5c51f124SMoriah Waterland <WHROOT>. { 520*5c51f124SMoriah Waterland if (status.pkg_rtn_done) { 521*5c51f124SMoriah Waterland status.pkg_rtn_done = 0; 522*5c51f124SMoriah Waterland BEGIN 0; 523*5c51f124SMoriah Waterland } else 524*5c51f124SMoriah Waterland REJECT; 525*5c51f124SMoriah Waterland } 526*5c51f124SMoriah Waterland <WHROOT>[ \t]+"-R"[ \t][\/\$]/[^ ^\t^\n] { 527*5c51f124SMoriah Waterland status.pkg_rtn_done = 1; 528*5c51f124SMoriah Waterland return (root_level); /* "-R" means locking is unlikely. */ 529*5c51f124SMoriah Waterland } 530*5c51f124SMoriah Waterland <WHROOT>[\n] { 531*5c51f124SMoriah Waterland if (status.pkg_rtn_done) { 532*5c51f124SMoriah Waterland status.pkg_rtn_done = 0; 533*5c51f124SMoriah Waterland line_no++; 534*5c51f124SMoriah Waterland BEGIN 0; 535*5c51f124SMoriah Waterland } else { 536*5c51f124SMoriah Waterland status.pkg_rtn_done = 1; 537*5c51f124SMoriah Waterland unput('\n'); 538*5c51f124SMoriah Waterland return (root_level | lock_level); /* No "-R". */ 539*5c51f124SMoriah Waterland } 540*5c51f124SMoriah Waterland } 541*5c51f124SMoriah Waterland <WHROOT>[;|>] { 542*5c51f124SMoriah Waterland status.pkg_rtn_done = 1; 543*5c51f124SMoriah Waterland return (root_level | lock_level); /* End of command without a "-R". */ 544*5c51f124SMoriah Waterland } 545*5c51f124SMoriah Waterland 546*5c51f124SMoriah Waterland \n { line_no++; status.allow_int = 0; } 547*5c51f124SMoriah Waterland . status.allow_int = 0; 548*5c51f124SMoriah Waterland %% 549*5c51f124SMoriah Waterland #include <stdio.h> 550*5c51f124SMoriah Waterland #include <limits.h> 551*5c51f124SMoriah Waterland #include <dirent.h> 552*5c51f124SMoriah Waterland #include <unistd.h> 553*5c51f124SMoriah Waterland #include <libintl.h> 554*5c51f124SMoriah Waterland 555*5c51f124SMoriah Waterland #ifdef DEBUG 556*5c51f124SMoriah Waterland /* 557*5c51f124SMoriah Waterland * Since this is a lex specification twice removed from the binary, 558*5c51f124SMoriah Waterland * I strongly recommend leaving the DEBUG portions in place. When new 559*5c51f124SMoriah Waterland * keywords are added, this will be very important. After modifying 560*5c51f124SMoriah Waterland * the specification, create an executable to test in this way. 561*5c51f124SMoriah Waterland * 562*5c51f124SMoriah Waterland * lex scriptvfy.l 563*5c51f124SMoriah Waterland * cc -o scriptvfy -g lex.yy.c $ROOT/usr/lib/libpkg.a \ 564*5c51f124SMoriah Waterland * -DDEBUG [-DVERBOSE] -ll -lintl 565*5c51f124SMoriah Waterland * scriptvfy test_directory 566*5c51f124SMoriah Waterland */ 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland main(int argc, char *argv[]) 569*5c51f124SMoriah Waterland { 570*5c51f124SMoriah Waterland int val; 571*5c51f124SMoriah Waterland 572*5c51f124SMoriah Waterland line_no = 1; 573*5c51f124SMoriah Waterland 574*5c51f124SMoriah Waterland if (argc == 1) { 575*5c51f124SMoriah Waterland printf("No directory provided.\n"); 576*5c51f124SMoriah Waterland exit(1); 577*5c51f124SMoriah Waterland } 578*5c51f124SMoriah Waterland 579*5c51f124SMoriah Waterland val = checkscripts(argv[1], 0); 580*5c51f124SMoriah Waterland 581*5c51f124SMoriah Waterland printf("return code is %d\n", val); 582*5c51f124SMoriah Waterland } 583*5c51f124SMoriah Waterland #endif 584*5c51f124SMoriah Waterland 585*5c51f124SMoriah Waterland /* 586*5c51f124SMoriah Waterland * This function evaluates the provided script and returns a bit string 587*5c51f124SMoriah Waterland * describing what patterns were located. 588*5c51f124SMoriah Waterland */ 589*5c51f124SMoriah Waterland static int 590*5c51f124SMoriah Waterland scripteval(char *script_name, char *script_path, int mask, int silent) 591*5c51f124SMoriah Waterland { 592*5c51f124SMoriah Waterland int val = 0; 593*5c51f124SMoriah Waterland int error = 0; 594*5c51f124SMoriah Waterland line_no = 1; 595*5c51f124SMoriah Waterland 596*5c51f124SMoriah Waterland if ((script_path == NULL) || (*script_path == NULL) || 597*5c51f124SMoriah Waterland (script_name == NULL)) { 598*5c51f124SMoriah Waterland logerr(gettext(ERR_ARGS)); 599*5c51f124SMoriah Waterland return (0); 600*5c51f124SMoriah Waterland } 601*5c51f124SMoriah Waterland 602*5c51f124SMoriah Waterland #ifdef VERBOSE 603*5c51f124SMoriah Waterland printf("Evaluating %s\n", script_path); 604*5c51f124SMoriah Waterland #endif 605*5c51f124SMoriah Waterland 606*5c51f124SMoriah Waterland if ((scr_fp = fopen(script_path, "r")) == NULL) { 607*5c51f124SMoriah Waterland logerr(gettext(ERR_FOPEN), script_path, errno); 608*5c51f124SMoriah Waterland return (0); 609*5c51f124SMoriah Waterland } 610*5c51f124SMoriah Waterland 611*5c51f124SMoriah Waterland #ifdef VERBOSE 612*5c51f124SMoriah Waterland printf("Openned script\n"); 613*5c51f124SMoriah Waterland #endif 614*5c51f124SMoriah Waterland 615*5c51f124SMoriah Waterland while (val = yylex()) { 616*5c51f124SMoriah Waterland #ifdef VERBOSE 617*5c51f124SMoriah Waterland printf(" Match is %s, returned 0x%x at line %d\n", 618*5c51f124SMoriah Waterland yytext, val, line_no); 619*5c51f124SMoriah Waterland printf(" in_function = %d, in_awk = %d, in_loop = %d, " \ 620*5c51f124SMoriah Waterland "in_case = %d, in_if = %d, in_pipe = %d\n", 621*5c51f124SMoriah Waterland status.in_function, status.in_awk, status.in_loop, 622*5c51f124SMoriah Waterland status.in_case, status.in_if, status.in_pipe); 623*5c51f124SMoriah Waterland printf(" loop_depth = %d, case_depth = %d, " \ 624*5c51f124SMoriah Waterland "if_depth = %d, pipe_release = %d, cur_level = %d\n", 625*5c51f124SMoriah Waterland loop_depth, case_depth, if_depth, pipe_release, cur_level); 626*5c51f124SMoriah Waterland #endif 627*5c51f124SMoriah Waterland 628*5c51f124SMoriah Waterland val &= mask; 629*5c51f124SMoriah Waterland if (val) { 630*5c51f124SMoriah Waterland error |= ((val & MAYBE_ONLY) ? 1 : 2); 631*5c51f124SMoriah Waterland 632*5c51f124SMoriah Waterland /* 633*5c51f124SMoriah Waterland * So at this point, val contains all status bits 634*5c51f124SMoriah Waterland * appropriate to this script. 635*5c51f124SMoriah Waterland */ 636*5c51f124SMoriah Waterland if (!silent) { 637*5c51f124SMoriah Waterland char *msg_ptr; 638*5c51f124SMoriah Waterland if (val & INTERACT_D) 639*5c51f124SMoriah Waterland msg_ptr = gettext(ERR_INTERACT); 640*5c51f124SMoriah Waterland else if (val & ROOT_D) 641*5c51f124SMoriah Waterland msg_ptr = gettext(ERR_ROOT); 642*5c51f124SMoriah Waterland else if (val & LOCKED_D) 643*5c51f124SMoriah Waterland msg_ptr = gettext(ERR_LOCKED); 644*5c51f124SMoriah Waterland else if (val & INTERACT_M) 645*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_INTERACT); 646*5c51f124SMoriah Waterland else if (val & ROOT_M) 647*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_ROOT); 648*5c51f124SMoriah Waterland else if (val & LOCKED_M) 649*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_LOCKED); 650*5c51f124SMoriah Waterland else if (val & WPARM1_M) 651*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_USE); 652*5c51f124SMoriah Waterland else if (val & USEPARM1_M) 653*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_USE); 654*5c51f124SMoriah Waterland else if (val & ODDPARM_M) 655*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_ARG); 656*5c51f124SMoriah Waterland else if (val & PKGDB_M) 657*5c51f124SMoriah Waterland msg_ptr = gettext(WRN_TRANSDB); 658*5c51f124SMoriah Waterland else 659*5c51f124SMoriah Waterland msg_ptr = gettext("unknown error"); 660*5c51f124SMoriah Waterland 661*5c51f124SMoriah Waterland logerr(msg_ptr, script_name, line_no); 662*5c51f124SMoriah Waterland } 663*5c51f124SMoriah Waterland } 664*5c51f124SMoriah Waterland } 665*5c51f124SMoriah Waterland 666*5c51f124SMoriah Waterland /* Warn if required about missing "-f" calls. */ 667*5c51f124SMoriah Waterland if (status.instf && !(status.instf_f)) 668*5c51f124SMoriah Waterland logerr(gettext(WRN_INST_F), script_name); 669*5c51f124SMoriah Waterland 670*5c51f124SMoriah Waterland if (status.remf && !(status.remf_f)) 671*5c51f124SMoriah Waterland logerr(gettext(WRN_REM_F), script_name); 672*5c51f124SMoriah Waterland 673*5c51f124SMoriah Waterland status.instf = status.instf_f = status.remf = status.remf_f = 0; 674*5c51f124SMoriah Waterland 675*5c51f124SMoriah Waterland /* Warn if installf was used but no space file is in place. */ 676*5c51f124SMoriah Waterland if (status.nospacefile && status.needspacefile) { 677*5c51f124SMoriah Waterland logerr(gettext(WRN_SPACEACC), script_name); 678*5c51f124SMoriah Waterland status.needspacefile = 0; 679*5c51f124SMoriah Waterland } 680*5c51f124SMoriah Waterland 681*5c51f124SMoriah Waterland status.in_pipe = 0; /* Pipes may dangle. */ 682*5c51f124SMoriah Waterland fclose(scr_fp); 683*5c51f124SMoriah Waterland 684*5c51f124SMoriah Waterland if (error == 3) 685*5c51f124SMoriah Waterland error = 2; 686*5c51f124SMoriah Waterland 687*5c51f124SMoriah Waterland return (error); 688*5c51f124SMoriah Waterland } 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland /* Test a preinstall or preremove script for validity. */ 691*5c51f124SMoriah Waterland int 692*5c51f124SMoriah Waterland pre_valid(char *script_name, char *script_path, int silent) 693*5c51f124SMoriah Waterland { 694*5c51f124SMoriah Waterland return (scripteval(script_name, script_path, PRE_MASK, silent)); 695*5c51f124SMoriah Waterland } 696*5c51f124SMoriah Waterland 697*5c51f124SMoriah Waterland /* Test a class action script for validity. */ 698*5c51f124SMoriah Waterland int 699*5c51f124SMoriah Waterland cas_valid(char *script_name, char *script_path, int silent) 700*5c51f124SMoriah Waterland { 701*5c51f124SMoriah Waterland return (scripteval(script_name, script_path, CAS_MASK, silent)); 702*5c51f124SMoriah Waterland } 703*5c51f124SMoriah Waterland 704*5c51f124SMoriah Waterland /* Test a postinstall or postremove script for validity. */ 705*5c51f124SMoriah Waterland int 706*5c51f124SMoriah Waterland post_valid(char *script_name, char *script_path, int silent) 707*5c51f124SMoriah Waterland { 708*5c51f124SMoriah Waterland return (scripteval(script_name, script_path, POST_MASK, silent)); 709*5c51f124SMoriah Waterland } 710*5c51f124SMoriah Waterland 711*5c51f124SMoriah Waterland /* Test a class action script for validity. */ 712*5c51f124SMoriah Waterland int 713*5c51f124SMoriah Waterland req_valid(char *script_name, char *script_path, int silent) 714*5c51f124SMoriah Waterland { 715*5c51f124SMoriah Waterland return (scripteval(script_name, script_path, REQ_MASK, silent)); 716*5c51f124SMoriah Waterland } 717*5c51f124SMoriah Waterland 718*5c51f124SMoriah Waterland 719*5c51f124SMoriah Waterland /* Test a class action script for validity. */ 720*5c51f124SMoriah Waterland int 721*5c51f124SMoriah Waterland chk_valid(char *script_name, char *script_path, int silent) 722*5c51f124SMoriah Waterland { 723*5c51f124SMoriah Waterland return (scripteval(script_name, script_path, CHK_MASK, silent)); 724*5c51f124SMoriah Waterland } 725*5c51f124SMoriah Waterland 726*5c51f124SMoriah Waterland /* This tests all of the scripts in the provided directory. */ 727*5c51f124SMoriah Waterland int 728*5c51f124SMoriah Waterland checkscripts(char *inst_dir, int silent) 729*5c51f124SMoriah Waterland { 730*5c51f124SMoriah Waterland DIR *dirfp; 731*5c51f124SMoriah Waterland struct dirent *dp; 732*5c51f124SMoriah Waterland char path[PATH_MAX]; 733*5c51f124SMoriah Waterland int retval = 0; 734*5c51f124SMoriah Waterland 735*5c51f124SMoriah Waterland /* For future reference, determine if a space file is present. */ 736*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, "space"); 737*5c51f124SMoriah Waterland if (access(path, F_OK) != 0) 738*5c51f124SMoriah Waterland status.nospacefile = 1; 739*5c51f124SMoriah Waterland 740*5c51f124SMoriah Waterland if ((dirfp = opendir(inst_dir)) == NULL) 741*5c51f124SMoriah Waterland return (0); 742*5c51f124SMoriah Waterland 743*5c51f124SMoriah Waterland while ((dp = readdir(dirfp)) != NULL) { 744*5c51f124SMoriah Waterland #ifdef VERBOSE 745*5c51f124SMoriah Waterland printf("Looking at file %s\n", dp->d_name); 746*5c51f124SMoriah Waterland #endif 747*5c51f124SMoriah Waterland if (dp->d_name[0] == '.') 748*5c51f124SMoriah Waterland continue; 749*5c51f124SMoriah Waterland 750*5c51f124SMoriah Waterland if ((strcmp(dp->d_name, "preinstall") == 0) || 751*5c51f124SMoriah Waterland (strcmp(dp->d_name, "preremove") == 0)) { 752*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 753*5c51f124SMoriah Waterland retval |= pre_valid(dp->d_name, path, silent); 754*5c51f124SMoriah Waterland continue; 755*5c51f124SMoriah Waterland } 756*5c51f124SMoriah Waterland 757*5c51f124SMoriah Waterland if ((strncmp(dp->d_name, "i.", 2) == 0) || 758*5c51f124SMoriah Waterland (strncmp(dp->d_name, "r.", 2) == 0)) { 759*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 760*5c51f124SMoriah Waterland retval |= cas_valid(dp->d_name, path, silent); 761*5c51f124SMoriah Waterland continue; 762*5c51f124SMoriah Waterland } 763*5c51f124SMoriah Waterland 764*5c51f124SMoriah Waterland if ((strcmp(dp->d_name, "postinstall") == 0) || 765*5c51f124SMoriah Waterland (strcmp(dp->d_name, "postremove") == 0)) { 766*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 767*5c51f124SMoriah Waterland retval |= post_valid(dp->d_name, path, silent); 768*5c51f124SMoriah Waterland continue; 769*5c51f124SMoriah Waterland } 770*5c51f124SMoriah Waterland 771*5c51f124SMoriah Waterland if (strcmp(dp->d_name, "request") == 0) { 772*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 773*5c51f124SMoriah Waterland retval |= req_valid(dp->d_name, path, silent); 774*5c51f124SMoriah Waterland continue; 775*5c51f124SMoriah Waterland } 776*5c51f124SMoriah Waterland if (strcmp(dp->d_name, "checkinstall") == 0) { 777*5c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 778*5c51f124SMoriah Waterland retval |= chk_valid(dp->d_name, path, silent); 779*5c51f124SMoriah Waterland continue; 780*5c51f124SMoriah Waterland } 781*5c51f124SMoriah Waterland } 782*5c51f124SMoriah Waterland 783*5c51f124SMoriah Waterland (void) closedir(dirfp); 784*5c51f124SMoriah Waterland 785*5c51f124SMoriah Waterland return (retval); 786*5c51f124SMoriah Waterland } 787