15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 23*24e7a8c7SPaul Wernau * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* 285c51f124SMoriah Waterland * The purpose of this lex specification is to estimate the 295c51f124SMoriah Waterland * correctness of the various scripts that accompany packages. It 305c51f124SMoriah Waterland * is not flawless, but it is a better review than that of prior 315c51f124SMoriah Waterland * package validators. It looks for indications of interaction, 325c51f124SMoriah Waterland * root calls and attempts to modify locked files. 335c51f124SMoriah Waterland */ 345c51f124SMoriah Waterland %e 1500 355c51f124SMoriah Waterland %p 3500 365c51f124SMoriah Waterland %s WHROOT 375c51f124SMoriah Waterland %{ 385c51f124SMoriah Waterland #undef input 395c51f124SMoriah Waterland #undef unput 405c51f124SMoriah Waterland FILE *scr_fp; 415c51f124SMoriah Waterland #define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(scr_fp))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) 425c51f124SMoriah Waterland #define unput(p) ungetc(p, scr_fp) 435c51f124SMoriah Waterland 445c51f124SMoriah Waterland #define INTERACT_D 0x00000001 /* definitely */ 455c51f124SMoriah Waterland #define ROOT_D 0x00000002 465c51f124SMoriah Waterland #define LOCKED_D 0x00000004 475c51f124SMoriah Waterland #define INTERACT_M 0x00010000 /* might be true, or we ... */ 485c51f124SMoriah Waterland #define ROOT_M 0x00020000 /* ... might be reading it wrong. */ 495c51f124SMoriah Waterland #define LOCKED_M 0x00040000 505c51f124SMoriah Waterland #define WPARM1_M 0x00080000 /* attempt to write to $1 */ 515c51f124SMoriah Waterland #define USEPARM1_M 0x00100000 /* other attempt to use $1 */ 525c51f124SMoriah Waterland #define ODDPARM_M 0x00200000 /* use of some other parameter */ 535c51f124SMoriah Waterland #define PKGDB_M 0x00400000 /* read access to DB */ 545c51f124SMoriah Waterland #define INITVAL 0x40000000 555c51f124SMoriah Waterland 565c51f124SMoriah Waterland /* Abbreviations */ 575c51f124SMoriah Waterland #define INTERACT (INTERACT_D | INTERACT_M) 585c51f124SMoriah Waterland #define ROOT (ROOT_D | ROOT_M) 595c51f124SMoriah Waterland #define LOCKED (LOCKED_D | LOCKED_M) 605c51f124SMoriah Waterland #define HASPARM (WPARM1_M | USEPARM1_M | ODDPARM_M) 615c51f124SMoriah Waterland 625c51f124SMoriah Waterland /* Things the preinstall and preremove scripts can't do. */ 635c51f124SMoriah Waterland #define PRE_MASK (INTERACT | LOCKED | PKGDB_M | HASPARM) 645c51f124SMoriah Waterland /* 655c51f124SMoriah Waterland * Things the class action script can't do. Don't get the impression that 665c51f124SMoriah Waterland * this means the class action script can be interactive; but, it can 675c51f124SMoriah Waterland * legitimately read stdin (which is what INTERACT tests for). 685c51f124SMoriah Waterland */ 695c51f124SMoriah Waterland #define CAS_MASK (LOCKED | PKGDB_M | WPARM1_M | ODDPARM_M) 705c51f124SMoriah Waterland /* Things the postinstall and postremove scripts can't do. */ 715c51f124SMoriah Waterland #define POST_MASK (INTERACT | HASPARM) 725c51f124SMoriah Waterland /* Things the request script can't do. */ 735c51f124SMoriah Waterland #define REQ_MASK (ROOT | ODDPARM_M) 745c51f124SMoriah Waterland /* Things the checkinstall script can't do. */ 755c51f124SMoriah Waterland #define CHK_MASK (INTERACT | ROOT | ODDPARM_M) 765c51f124SMoriah Waterland 775c51f124SMoriah Waterland /* Nothing definite - not worth returning an error */ 785c51f124SMoriah Waterland #define MAYBE_ONLY ~(INTERACT_D | ROOT_D | LOCKED_D) 795c51f124SMoriah Waterland 805c51f124SMoriah Waterland #define WRN_INST_F "WARNING: script <%s> uses installf but no " \ 815c51f124SMoriah Waterland "installf -f was detected." 825c51f124SMoriah Waterland #define WRN_REM_F "WARNING: script <%s> uses removef but no " \ 835c51f124SMoriah Waterland "removef -f was detected." 845c51f124SMoriah Waterland #define WRN_INTERACT "WARNING: script <%s> may require " \ 855c51f124SMoriah Waterland "user interaction at line <%d>." 865c51f124SMoriah Waterland #define WRN_LOCKED "WARNING: script <%s> may seek access to the " \ 875c51f124SMoriah Waterland "transitional package database at line <%d>. " \ 885c51f124SMoriah Waterland "This is safest in the postinstall or " \ 895c51f124SMoriah Waterland "postremove script." 905c51f124SMoriah Waterland #define WRN_ROOT "WARNING: script <%s> may not have permission " \ 915c51f124SMoriah Waterland "to execute line <%d>." 925c51f124SMoriah Waterland #define WRN_FORM_ARG "WARNING: not sure where script <%s> gets the "\ 935c51f124SMoriah Waterland "parameter at line <%d>." 945c51f124SMoriah Waterland #define WRN_FORM_USE "WARNING: script <%s> questionable usage of "\ 955c51f124SMoriah Waterland "parameter at line <%d>." 965c51f124SMoriah Waterland #define WRN_TRANSDB "WARNING: script <%s> questionable read " \ 975c51f124SMoriah Waterland "of package database at line <%d>. An " \ 985c51f124SMoriah Waterland "intermediate buffer may be appropriate." 995c51f124SMoriah Waterland #define WRN_SPACEACC "WARNING: script <%s> updates the package database " \ 1005c51f124SMoriah Waterland "but provides no space file to account for " \ 1015c51f124SMoriah Waterland "the additional package object." 1025c51f124SMoriah Waterland #define ERR_INTERACT "ERROR: script <%s> requires user " \ 1035c51f124SMoriah Waterland "interaction at line <%d>." 1045c51f124SMoriah Waterland #define ERR_LOCKED "ERROR: script <%s> attempts to modify locked " \ 1055c51f124SMoriah Waterland "package database at line <%d>." 1065c51f124SMoriah Waterland #define ERR_ROOT "ERROR: script <%s> requires root permission at " \ 1075c51f124SMoriah Waterland "line <%d>." 1085c51f124SMoriah Waterland #define ERR_FOPEN "ERROR: Cannot evaluate script <%s>, errno=%d." 1095c51f124SMoriah Waterland #define ERR_ARGS "ERROR: scripteval() - no script provided for " \ 1105c51f124SMoriah Waterland "evaluation." 1115c51f124SMoriah Waterland extern int errno; 1125c51f124SMoriah Waterland 1135c51f124SMoriah Waterland static int line_no; /* current line number */ 1145c51f124SMoriah Waterland int pipe_release = 0; /* loop level for release of pipe */ 1155c51f124SMoriah Waterland int loop_depth = 0; /* current number of nested loops */ 1165c51f124SMoriah Waterland int case_depth = 0; /* same for case ... */ 1175c51f124SMoriah Waterland int if_depth = 0; /* ... and if statements */ 1185c51f124SMoriah Waterland int cur_level = 0; /* current number of nested anything */ 1195c51f124SMoriah Waterland int braces = 0; /* depth into a function */ 1205c51f124SMoriah Waterland 1215c51f124SMoriah Waterland int lock_level = 0; 1225c51f124SMoriah Waterland int root_level = 0; 1235c51f124SMoriah Waterland 1245c51f124SMoriah Waterland struct statstrct { 1255c51f124SMoriah Waterland unsigned int in_function:1; 1265c51f124SMoriah Waterland unsigned int in_pipe:1; 1275c51f124SMoriah Waterland unsigned int in_loop:1; 1285c51f124SMoriah Waterland unsigned int in_case:1; 1295c51f124SMoriah Waterland unsigned int in_if:1; 1305c51f124SMoriah Waterland unsigned int in_awk:1; 1315c51f124SMoriah Waterland unsigned int allow_int:1; /* Allow an interactive function. */ 1325c51f124SMoriah Waterland unsigned int pkg_rtn_done:1; 1335c51f124SMoriah Waterland unsigned int pkgchk_f:1; 1345c51f124SMoriah Waterland unsigned int instf:1; 1355c51f124SMoriah Waterland unsigned int instf_f:1; 1365c51f124SMoriah Waterland unsigned int remf:1; 1375c51f124SMoriah Waterland unsigned int remf_f:1; 1385c51f124SMoriah Waterland unsigned int nospacefile:1; 1395c51f124SMoriah Waterland unsigned int needspacefile:1; 1405c51f124SMoriah Waterland } status = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 1415c51f124SMoriah Waterland 1425c51f124SMoriah Waterland %} 1435c51f124SMoriah Waterland %% 1445c51f124SMoriah Waterland %{ 1455c51f124SMoriah Waterland /* 1465c51f124SMoriah Waterland * Validate a few OK patterns that look like bad patterns. These include: 1475c51f124SMoriah Waterland * 1. comments 1485c51f124SMoriah Waterland * 2. quoted strings 1495c51f124SMoriah Waterland * 3. writes to $1 (request script) 1505c51f124SMoriah Waterland * 4. reads from $1 (CAS) 1515c51f124SMoriah Waterland * 5. writes to /dev/null 1525c51f124SMoriah Waterland */ 1535c51f124SMoriah Waterland %} 154*24e7a8c7SPaul Wernau #.*$ { 155*24e7a8c7SPaul Wernau if (status.in_awk == 0) 156*24e7a8c7SPaul Wernau return INITVAL; 157*24e7a8c7SPaul Wernau else 158*24e7a8c7SPaul Wernau REJECT; /* No comments in the middle of an awk statement */ 159*24e7a8c7SPaul Wernau } 1605c51f124SMoriah Waterland 1615c51f124SMoriah Waterland \` unput(' '); /* No executable matching */ 1625c51f124SMoriah Waterland 1635c51f124SMoriah Waterland %{ 1645c51f124SMoriah Waterland /* Anybody can write to /dev/null and anybody can write to /tmp. */ 1655c51f124SMoriah Waterland %} 1665c51f124SMoriah Waterland \>[ \t]*"/dev/null" return INITVAL; 1675c51f124SMoriah Waterland \>[ \t]*"/tmp" return INITVAL; 1685c51f124SMoriah Waterland 1695c51f124SMoriah Waterland %{ 1705c51f124SMoriah Waterland /* If it's escaped, the next entry may as well be a space. */ 1715c51f124SMoriah Waterland %} 1725c51f124SMoriah Waterland \\ { 1735c51f124SMoriah Waterland char ch; 1745c51f124SMoriah Waterland 1755c51f124SMoriah Waterland if ((ch = input()) == '\n') 1765c51f124SMoriah Waterland line_no++; 1775c51f124SMoriah Waterland 1785c51f124SMoriah Waterland unput(' '); 1795c51f124SMoriah Waterland } 1805c51f124SMoriah Waterland 1815c51f124SMoriah Waterland %{ 1825c51f124SMoriah Waterland /* In the quotes is OK. */ 1835c51f124SMoriah Waterland %} 1845c51f124SMoriah Waterland \" { 1855c51f124SMoriah Waterland char ch; 1865c51f124SMoriah Waterland while ((ch = input()) != '\"') { 1875c51f124SMoriah Waterland if (ch == '\\') { 1885c51f124SMoriah Waterland input(); /* Read this into the bit bucket. */ 1895c51f124SMoriah Waterland continue; 1905c51f124SMoriah Waterland } 1915c51f124SMoriah Waterland if (ch == '\n') 1925c51f124SMoriah Waterland line_no++; 1935c51f124SMoriah Waterland else if (ch == '\0') 1945c51f124SMoriah Waterland return (0); /* EOF */ 1955c51f124SMoriah Waterland } 1965c51f124SMoriah Waterland } 1975c51f124SMoriah Waterland 1985c51f124SMoriah Waterland %{ 1995c51f124SMoriah Waterland /* In the single quotes is OK if they aren't associated with an awk script. */ 2005c51f124SMoriah Waterland %} 2015c51f124SMoriah Waterland \' { 2025c51f124SMoriah Waterland char ch; 2035c51f124SMoriah Waterland 204*24e7a8c7SPaul Wernau if (status.in_awk != 0) { 2055c51f124SMoriah Waterland REJECT;; 206*24e7a8c7SPaul Wernau } 2075c51f124SMoriah Waterland 2085c51f124SMoriah Waterland while ((ch = input()) != '\'') { 2095c51f124SMoriah Waterland if (ch == '\\') { 2105c51f124SMoriah Waterland input(); /* Read this into the bit bucket. */ 2115c51f124SMoriah Waterland continue; 2125c51f124SMoriah Waterland } 2135c51f124SMoriah Waterland if (ch == '\n') 2145c51f124SMoriah Waterland line_no++; 2155c51f124SMoriah Waterland else if (ch == '\0') 2165c51f124SMoriah Waterland return (0); /* EOF */ 2175c51f124SMoriah Waterland } 2185c51f124SMoriah Waterland } 2195c51f124SMoriah Waterland 2205c51f124SMoriah Waterland %{ 2215c51f124SMoriah Waterland /* 2225c51f124SMoriah Waterland * Check for use of parameters passed to the script. 2235c51f124SMoriah Waterland * 1. writes to $1 as though it were a file 2245c51f124SMoriah Waterland * 2. use of $1 in any capacity 2255c51f124SMoriah Waterland * 3. use of other parameters 2265c51f124SMoriah Waterland * Within a function or an awk script, these parameters aren't 2275c51f124SMoriah Waterland * the one's of interest. 2285c51f124SMoriah Waterland */ 2295c51f124SMoriah Waterland %} 2305c51f124SMoriah Waterland \>[\t ]*\$1/[\t\n ] { 2315c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 2325c51f124SMoriah Waterland return (WPARM1_M); 2335c51f124SMoriah Waterland } 2345c51f124SMoriah Waterland 2355c51f124SMoriah Waterland ^$1/[\t\n ] | 2365c51f124SMoriah Waterland [\t ]$1/[\t\n ] { 2375c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 2385c51f124SMoriah Waterland return (USEPARM1_M); 2395c51f124SMoriah Waterland } 2405c51f124SMoriah Waterland 2415c51f124SMoriah Waterland \$[2-9] | 2425c51f124SMoriah Waterland \$[0-9][0-9]+ { 2435c51f124SMoriah Waterland if (status.in_function == 0 && status.in_awk == 0) 2445c51f124SMoriah Waterland return (ODDPARM_M); 2455c51f124SMoriah Waterland } 2465c51f124SMoriah Waterland 2475c51f124SMoriah Waterland %{ 2485c51f124SMoriah Waterland /* 2495c51f124SMoriah Waterland * Detect shell function. 2505c51f124SMoriah Waterland */ 2515c51f124SMoriah Waterland %} 2525c51f124SMoriah Waterland "()"[ \t]*\n[ \t]*/\{ { status.in_function = 1; line_no++; } 2535c51f124SMoriah Waterland "()"[ ]*/\{ status.in_function = 1; 2545c51f124SMoriah Waterland 2555c51f124SMoriah Waterland "{" { 2565c51f124SMoriah Waterland if (status.in_function == 1) 2575c51f124SMoriah Waterland braces++; 2585c51f124SMoriah Waterland } 2595c51f124SMoriah Waterland 2605c51f124SMoriah Waterland "}" { 2615c51f124SMoriah Waterland if (status.in_function == 1) { 2625c51f124SMoriah Waterland braces--; 2635c51f124SMoriah Waterland if (braces == 0) 2645c51f124SMoriah Waterland status.in_function = 0; 2655c51f124SMoriah Waterland } 2665c51f124SMoriah Waterland } 2675c51f124SMoriah Waterland 2685c51f124SMoriah Waterland %{ 2695c51f124SMoriah Waterland /* 2705c51f124SMoriah Waterland * Detect for or while loop. 2715c51f124SMoriah Waterland */ 2725c51f124SMoriah Waterland %} 2735c51f124SMoriah Waterland ^for/[\t\n ] | 274*24e7a8c7SPaul Wernau ^[\t ]+for/[\t\n ] | 2755c51f124SMoriah Waterland ^while/[\t\n ] | 276*24e7a8c7SPaul Wernau ^[\t ]+while/[\t\n ] { 2775c51f124SMoriah Waterland status.in_loop = 1; 2785c51f124SMoriah Waterland loop_depth++; 2795c51f124SMoriah Waterland cur_level++; 2805c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 2815c51f124SMoriah Waterland } 2825c51f124SMoriah Waterland 2835c51f124SMoriah Waterland ^done/[\t\n ] | 284*24e7a8c7SPaul Wernau ^[\t ]+done/[\t\n ] { 285*24e7a8c7SPaul Wernau if (status.in_loop == 1) { 2865c51f124SMoriah Waterland loop_depth--; 2875c51f124SMoriah Waterland cur_level--; 2885c51f124SMoriah Waterland if (loop_depth == 0) 2895c51f124SMoriah Waterland status.in_loop = 0; 2905c51f124SMoriah Waterland } 291*24e7a8c7SPaul Wernau } 2925c51f124SMoriah Waterland 2935c51f124SMoriah Waterland %{ 2945c51f124SMoriah Waterland /* 2955c51f124SMoriah Waterland * Detect case. 2965c51f124SMoriah Waterland */ 2975c51f124SMoriah Waterland %} 2985c51f124SMoriah Waterland ^case/[\t\n ] | 299*24e7a8c7SPaul Wernau ^[\t ]+case/[\t\n ] { 3005c51f124SMoriah Waterland status.in_case = 1; 3015c51f124SMoriah Waterland case_depth++; 3025c51f124SMoriah Waterland cur_level++; 3035c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 3045c51f124SMoriah Waterland } 3055c51f124SMoriah Waterland 3065c51f124SMoriah Waterland ^esac/[\t\n ] | 307*24e7a8c7SPaul Wernau ^[\t ]+esac/[\t\n ] { 308*24e7a8c7SPaul Wernau if (status.in_case == 1) { 3095c51f124SMoriah Waterland case_depth--; 3105c51f124SMoriah Waterland cur_level--; 3115c51f124SMoriah Waterland if (case_depth == 0) 3125c51f124SMoriah Waterland status.in_case = 0; 3135c51f124SMoriah Waterland } 314*24e7a8c7SPaul Wernau } 3155c51f124SMoriah Waterland 3165c51f124SMoriah Waterland %{ 3175c51f124SMoriah Waterland /* 3185c51f124SMoriah Waterland * Detect if. 3195c51f124SMoriah Waterland */ 3205c51f124SMoriah Waterland %} 3215c51f124SMoriah Waterland ^if" "*"[" | 322*24e7a8c7SPaul Wernau ^[\t ]+if" "*"[" { 3235c51f124SMoriah Waterland status.in_if = 1; 3245c51f124SMoriah Waterland if_depth++; 3255c51f124SMoriah Waterland cur_level++; 3265c51f124SMoriah Waterland REJECT; /* What's in the argument is important too. */ 3275c51f124SMoriah Waterland } 3285c51f124SMoriah Waterland 3295c51f124SMoriah Waterland ^fi/[\t\n ] | 330*24e7a8c7SPaul Wernau ^[\t ]+fi/[\t\n ] { 331*24e7a8c7SPaul Wernau if (status.in_if == 1) { 3325c51f124SMoriah Waterland if_depth--; 3335c51f124SMoriah Waterland cur_level--; 3345c51f124SMoriah Waterland if (if_depth == 0) 3355c51f124SMoriah Waterland status.in_if = 0; 3365c51f124SMoriah Waterland } 337*24e7a8c7SPaul Wernau } 3385c51f124SMoriah Waterland 3395c51f124SMoriah Waterland %{ 3405c51f124SMoriah Waterland /* 3415c51f124SMoriah Waterland * Detect awk or nawk function. If the function is enclosed in "`"s 3425c51f124SMoriah Waterland * the entire line will be grabbed., so we check for that possibility. 3435c51f124SMoriah Waterland */ 3445c51f124SMoriah Waterland %} 3455c51f124SMoriah Waterland ^n?awk[^\n^']*\' | 346*24e7a8c7SPaul Wernau [\t \\\(\/]n?awk[^\n^']*\' {status.in_awk = 1; 347*24e7a8c7SPaul Wernau #ifdef VERBOSE 348*24e7a8c7SPaul Wernau printf("open awk statment, line %d\n", line_no); 349*24e7a8c7SPaul Wernau #endif 350*24e7a8c7SPaul Wernau } 3515c51f124SMoriah Waterland 3525c51f124SMoriah Waterland 3535c51f124SMoriah Waterland \' { 354*24e7a8c7SPaul Wernau if (status.in_awk == 1) { 355*24e7a8c7SPaul Wernau #ifdef VERBOSE 356*24e7a8c7SPaul Wernau printf("close awk statement, line %d\n", line_no); 357*24e7a8c7SPaul Wernau #endif 3585c51f124SMoriah Waterland status.in_awk = 0; 3595c51f124SMoriah Waterland } 360*24e7a8c7SPaul Wernau } 3615c51f124SMoriah Waterland 3625c51f124SMoriah Waterland %{ 3635c51f124SMoriah Waterland /* Detect pipe target. */ 3645c51f124SMoriah Waterland %} 3655c51f124SMoriah Waterland [\$A-Za-z] { 366*24e7a8c7SPaul Wernau if (status.in_pipe == 1 && pipe_release == cur_level) { 3675c51f124SMoriah Waterland status.in_pipe = 0; /* target located */ 3685c51f124SMoriah Waterland pipe_release = 0; 369*24e7a8c7SPaul Wernau #ifdef VERBOSE 370*24e7a8c7SPaul Wernau printf("end pipe, line %d\n", line_no); 371*24e7a8c7SPaul Wernau #endif 3725c51f124SMoriah Waterland status.allow_int = 1; /* this isn't really interactive. */ 3735c51f124SMoriah Waterland REJECT; /* put it back */ 3745c51f124SMoriah Waterland } 3755c51f124SMoriah Waterland } 3765c51f124SMoriah Waterland 3775c51f124SMoriah Waterland %{ 3785c51f124SMoriah Waterland /* If it's a pipe, note that and continue. */ 3795c51f124SMoriah Waterland %} 3805c51f124SMoriah Waterland "||" | 3815c51f124SMoriah Waterland "|" { 3825c51f124SMoriah Waterland if (status.in_pipe == 0) { 3835c51f124SMoriah Waterland status.in_pipe = 1; 384*24e7a8c7SPaul Wernau #ifdef VERBOSE 385*24e7a8c7SPaul Wernau printf("start pipe, line %d\n", line_no); 386*24e7a8c7SPaul Wernau #endif 3875c51f124SMoriah Waterland pipe_release = cur_level; 3885c51f124SMoriah Waterland } 3895c51f124SMoriah Waterland } 3905c51f124SMoriah Waterland 3915c51f124SMoriah Waterland %{ 3925c51f124SMoriah Waterland /* 3935c51f124SMoriah Waterland * Test input for admin-type telltale interactive functions. Definite's 3945c51f124SMoriah Waterland * first, maybe's next. 3955c51f124SMoriah Waterland */ 3965c51f124SMoriah Waterland %} 3975c51f124SMoriah Waterland ^ckdate/[\t\n ] | 3985c51f124SMoriah Waterland [\t \/]ckdate/[\t\n ] | 3995c51f124SMoriah Waterland ^ckint/[\t\n ] | 4005c51f124SMoriah Waterland [\t \/]ckint/[\t\n ] | 4015c51f124SMoriah Waterland ^ckrange/[\t\n ] | 4025c51f124SMoriah Waterland [\t \/]ckrange/[\t\n ] | 4035c51f124SMoriah Waterland ^cktime/[\t\n ] | 4045c51f124SMoriah Waterland [\t \/]cktime/[\t\n ] | 4055c51f124SMoriah Waterland ^ckyorn/[\t\n ] | 4065c51f124SMoriah Waterland [\t \/]ckyorn/[\t\n ] | 4075c51f124SMoriah Waterland ^ckgid/[\t\n ] | 4085c51f124SMoriah Waterland [\t \/]ckgid/[\t\n ] | 4095c51f124SMoriah Waterland ^ckpath/[\t\n ] | 4105c51f124SMoriah Waterland [\t \/]ckpath/[\t\n ] | 4115c51f124SMoriah Waterland ^ckstr/[\t\n ] | 4125c51f124SMoriah Waterland [\t \/]ckstr/[\t\n ] | 4135c51f124SMoriah Waterland ^ckuid/[\t\n ] | 4145c51f124SMoriah Waterland [\t \/]ckuid/[\t\n ] { 4155c51f124SMoriah Waterland if (status.in_pipe == 1 || status.allow_int == 1) 4165c51f124SMoriah Waterland return (INITVAL); 4175c51f124SMoriah Waterland else 4185c51f124SMoriah Waterland return (INTERACT_M); /* maybe should be _D */ 4195c51f124SMoriah Waterland } 4205c51f124SMoriah Waterland 4215c51f124SMoriah Waterland ^read/[\t\n ] | 4225c51f124SMoriah Waterland [\t ]read/[\t\n ] | 4235c51f124SMoriah Waterland "=[ ]+&<"[\t ] { 4245c51f124SMoriah Waterland if (status.in_pipe == 1 || status.allow_int == 1) 4255c51f124SMoriah Waterland return (INITVAL); 4265c51f124SMoriah Waterland else 4275c51f124SMoriah Waterland return (INTERACT_M); 4285c51f124SMoriah Waterland } 4295c51f124SMoriah Waterland 4305c51f124SMoriah Waterland %{ 4315c51f124SMoriah Waterland /* Scan for root authority commands. Definite's first, maybe's next. */ 4325c51f124SMoriah Waterland %} 4335c51f124SMoriah Waterland ^mkdir/[\t\n ] | 4345c51f124SMoriah Waterland [\t \/]mkdir/[\t\n ] | 4355c51f124SMoriah Waterland ^mv/[\t\n ] | 4365c51f124SMoriah Waterland [\t \/]mv/[\t\n ] | 4375c51f124SMoriah Waterland ^cpio/[\t\n ] | 4385c51f124SMoriah Waterland [\t \/]cpio/[\t\n ] | 4395c51f124SMoriah Waterland ^tar/[\t\n ] | 4405c51f124SMoriah Waterland [\t \/]tar/[\t\n ] | 4415c51f124SMoriah Waterland ^(un)?compress/[\t\n ] | 4425c51f124SMoriah Waterland [\t \/](un)?compress/[\t\n ] | 4435c51f124SMoriah Waterland ^rmdir/[\t\n ] | 4445c51f124SMoriah Waterland [\t \/]rmdir/[\t\n ] return (ROOT_D); 4455c51f124SMoriah Waterland 4465c51f124SMoriah Waterland ^r?cp(dir)?/[\t\n ] | 4475c51f124SMoriah Waterland [\t \/]r?cp(dir)?/[\t\n ] | 4485c51f124SMoriah Waterland ^rm/[\t\n ] | 4495c51f124SMoriah Waterland [\t \/]rm/[\t\n ] | 4505c51f124SMoriah Waterland \>[ \t]*[\$\/a-zA-Z0-9] return (ROOT_M); 4515c51f124SMoriah Waterland 4525c51f124SMoriah Waterland %{ 4535c51f124SMoriah Waterland /* These root commands may also be locked. */ 4545c51f124SMoriah Waterland 4555c51f124SMoriah 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. */ 4565c51f124SMoriah Waterland %} 4575c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-f" | 4585c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-f" { 4595c51f124SMoriah Waterland status.pkgchk_f = 1; 4605c51f124SMoriah Waterland REJECT; /* We need the intermediate args. */ 4615c51f124SMoriah Waterland } 4625c51f124SMoriah Waterland 4635c51f124SMoriah Waterland %{ 4645c51f124SMoriah Waterland /* If it's "pkgchk ... -R ..." then the local package database is not being tested and no database warning is necessary. */ 4655c51f124SMoriah Waterland %} 4665c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n] | 4675c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n] { 4685c51f124SMoriah Waterland if (status.pkgchk_f) 4695c51f124SMoriah Waterland return (ROOT_D); 4705c51f124SMoriah Waterland else 4715c51f124SMoriah Waterland return (INITVAL); 4725c51f124SMoriah Waterland } 4735c51f124SMoriah Waterland 4745c51f124SMoriah Waterland %{ 4755c51f124SMoriah 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. */ 4765c51f124SMoriah Waterland %} 4775c51f124SMoriah Waterland ^pkgchk/[\t\n ] | 4785c51f124SMoriah Waterland [\t \/]pkgchk/[\t\n ] { 4795c51f124SMoriah Waterland if (status.pkgchk_f) { 4805c51f124SMoriah Waterland status.pkgchk_f = 0; 4815c51f124SMoriah Waterland return (ROOT_D | PKGDB_M); 4825c51f124SMoriah Waterland } else 4835c51f124SMoriah Waterland return (PKGDB_M); 4845c51f124SMoriah Waterland } 4855c51f124SMoriah Waterland 4865c51f124SMoriah Waterland %{ 4875c51f124SMoriah 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. */ 4885c51f124SMoriah Waterland 4895c51f124SMoriah Waterland /* First test for a "-f" argument. */ 4905c51f124SMoriah Waterland %} 4915c51f124SMoriah Waterland ^installf[^\n^|^>^;]*"-f" | 4925c51f124SMoriah Waterland [\t \/]installf[^\n^|^>^;]*"-f" { 4935c51f124SMoriah Waterland status.instf_f = 1; 4945c51f124SMoriah Waterland 4955c51f124SMoriah Waterland REJECT; /* The whole line needs to be re-reviewed. */ 4965c51f124SMoriah Waterland } 4975c51f124SMoriah Waterland 4985c51f124SMoriah Waterland ^removef[^\n^|^>^;]*"-f" | 4995c51f124SMoriah Waterland [\t \/]removef[^\n^|^>^;]*"-f" { 5005c51f124SMoriah Waterland status.remf_f = 1; 5015c51f124SMoriah Waterland 5025c51f124SMoriah Waterland REJECT; /* The whole line needs to be re-reviewed. */ 5035c51f124SMoriah Waterland } 5045c51f124SMoriah Waterland 5055c51f124SMoriah Waterland ^installf/[\t\n ] | 5065c51f124SMoriah Waterland [\t \/]installf/[\t\n ] { 5075c51f124SMoriah Waterland status.instf = 1; 5085c51f124SMoriah Waterland status.needspacefile = 1; 5095c51f124SMoriah Waterland 5105c51f124SMoriah Waterland root_level = ROOT_D; 5115c51f124SMoriah Waterland lock_level = LOCKED_M; 5125c51f124SMoriah Waterland 5135c51f124SMoriah Waterland BEGIN WHROOT; 5145c51f124SMoriah Waterland } 5155c51f124SMoriah Waterland 5165c51f124SMoriah Waterland ^removef/[\t\n ] | 5175c51f124SMoriah Waterland [\t \/]removef/[\t\n ] { 5185c51f124SMoriah Waterland status.remf = 1; 5195c51f124SMoriah Waterland 5205c51f124SMoriah Waterland root_level = ROOT_D; 5215c51f124SMoriah Waterland lock_level = LOCKED_M; 5225c51f124SMoriah Waterland BEGIN WHROOT; 5235c51f124SMoriah Waterland } 5245c51f124SMoriah Waterland 5255c51f124SMoriah Waterland %{ 5265c51f124SMoriah 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. */ 5275c51f124SMoriah Waterland %} 5285c51f124SMoriah Waterland ^pkgadd/[\t\n ] | 5295c51f124SMoriah Waterland [\t \/]pkgadd/[\t\n ] | 5305c51f124SMoriah Waterland ^pkgrm/[\t\n ] | 5315c51f124SMoriah Waterland [\t \/]pkgrm/[\t\n ] { 5325c51f124SMoriah Waterland root_level = ROOT_D; 5335c51f124SMoriah Waterland lock_level = LOCKED_D; 5345c51f124SMoriah Waterland BEGIN WHROOT; 5355c51f124SMoriah Waterland } 5365c51f124SMoriah Waterland 5375c51f124SMoriah Waterland %{ 5385c51f124SMoriah Waterland /* The only way to get here is if we are in the middle of a pkg command. */ 5395c51f124SMoriah Waterland %} 5405c51f124SMoriah Waterland <WHROOT>. { 5415c51f124SMoriah Waterland if (status.pkg_rtn_done) { 5425c51f124SMoriah Waterland status.pkg_rtn_done = 0; 5435c51f124SMoriah Waterland BEGIN 0; 5445c51f124SMoriah Waterland } else 5455c51f124SMoriah Waterland REJECT; 5465c51f124SMoriah Waterland } 5475c51f124SMoriah Waterland <WHROOT>[ \t]+"-R"[ \t][\/\$]/[^ ^\t^\n] { 5485c51f124SMoriah Waterland status.pkg_rtn_done = 1; 5495c51f124SMoriah Waterland return (root_level); /* "-R" means locking is unlikely. */ 5505c51f124SMoriah Waterland } 5515c51f124SMoriah Waterland <WHROOT>[\n] { 5525c51f124SMoriah Waterland if (status.pkg_rtn_done) { 5535c51f124SMoriah Waterland status.pkg_rtn_done = 0; 5545c51f124SMoriah Waterland line_no++; 5555c51f124SMoriah Waterland BEGIN 0; 5565c51f124SMoriah Waterland } else { 5575c51f124SMoriah Waterland status.pkg_rtn_done = 1; 5585c51f124SMoriah Waterland unput('\n'); 5595c51f124SMoriah Waterland return (root_level | lock_level); /* No "-R". */ 5605c51f124SMoriah Waterland } 5615c51f124SMoriah Waterland } 5625c51f124SMoriah Waterland <WHROOT>[;|>] { 5635c51f124SMoriah Waterland status.pkg_rtn_done = 1; 5645c51f124SMoriah Waterland return (root_level | lock_level); /* End of command without a "-R". */ 5655c51f124SMoriah Waterland } 5665c51f124SMoriah Waterland 567*24e7a8c7SPaul Wernau \n { line_no++; status.allow_int = 0; 568*24e7a8c7SPaul Wernau #ifdef VERBOSE 569*24e7a8c7SPaul Wernau printf("allow_int = 0\n"); 570*24e7a8c7SPaul Wernau #endif 571*24e7a8c7SPaul Wernau } 572*24e7a8c7SPaul Wernau 573*24e7a8c7SPaul Wernau . { 574*24e7a8c7SPaul Wernau /* 575*24e7a8c7SPaul Wernau XXX - bug - resets prematurely if we pipe into a while loop or 576*24e7a8c7SPaul Wernau other such construct 577*24e7a8c7SPaul Wernau status.allow_int = 0; 578*24e7a8c7SPaul Wernau */ 579*24e7a8c7SPaul Wernau } 580*24e7a8c7SPaul Wernau 5815c51f124SMoriah Waterland %% 5825c51f124SMoriah Waterland #include <stdio.h> 5835c51f124SMoriah Waterland #include <limits.h> 5845c51f124SMoriah Waterland #include <dirent.h> 5855c51f124SMoriah Waterland #include <unistd.h> 5865c51f124SMoriah Waterland #include <libintl.h> 5875c51f124SMoriah Waterland 5885c51f124SMoriah Waterland #ifdef DEBUG 5895c51f124SMoriah Waterland /* 5905c51f124SMoriah Waterland * Since this is a lex specification twice removed from the binary, 5915c51f124SMoriah Waterland * I strongly recommend leaving the DEBUG portions in place. When new 5925c51f124SMoriah Waterland * keywords are added, this will be very important. After modifying 5935c51f124SMoriah Waterland * the specification, create an executable to test in this way. 5945c51f124SMoriah Waterland * 5955c51f124SMoriah Waterland * lex scriptvfy.l 5965c51f124SMoriah Waterland * cc -o scriptvfy -g lex.yy.c $ROOT/usr/lib/libpkg.a \ 5975c51f124SMoriah Waterland * -DDEBUG [-DVERBOSE] -ll -lintl 5985c51f124SMoriah Waterland * scriptvfy test_directory 5995c51f124SMoriah Waterland */ 6005c51f124SMoriah Waterland 6015c51f124SMoriah Waterland main(int argc, char *argv[]) 6025c51f124SMoriah Waterland { 6035c51f124SMoriah Waterland int val; 6045c51f124SMoriah Waterland 6055c51f124SMoriah Waterland line_no = 1; 6065c51f124SMoriah Waterland 6075c51f124SMoriah Waterland if (argc == 1) { 6085c51f124SMoriah Waterland printf("No directory provided.\n"); 6095c51f124SMoriah Waterland exit(1); 6105c51f124SMoriah Waterland } 6115c51f124SMoriah Waterland 6125c51f124SMoriah Waterland val = checkscripts(argv[1], 0); 6135c51f124SMoriah Waterland 6145c51f124SMoriah Waterland printf("return code is %d\n", val); 6155c51f124SMoriah Waterland } 6165c51f124SMoriah Waterland #endif 6175c51f124SMoriah Waterland 6185c51f124SMoriah Waterland /* 6195c51f124SMoriah Waterland * This function evaluates the provided script and returns a bit string 6205c51f124SMoriah Waterland * describing what patterns were located. 6215c51f124SMoriah Waterland */ 6225c51f124SMoriah Waterland static int 6235c51f124SMoriah Waterland scripteval(char *script_name, char *script_path, int mask, int silent) 6245c51f124SMoriah Waterland { 6255c51f124SMoriah Waterland int val = 0; 6265c51f124SMoriah Waterland int error = 0; 6275c51f124SMoriah Waterland line_no = 1; 6285c51f124SMoriah Waterland 6295c51f124SMoriah Waterland if ((script_path == NULL) || (*script_path == NULL) || 6305c51f124SMoriah Waterland (script_name == NULL)) { 6315c51f124SMoriah Waterland logerr(gettext(ERR_ARGS)); 6325c51f124SMoriah Waterland return (0); 6335c51f124SMoriah Waterland } 6345c51f124SMoriah Waterland 6355c51f124SMoriah Waterland #ifdef VERBOSE 6365c51f124SMoriah Waterland printf("Evaluating %s\n", script_path); 6375c51f124SMoriah Waterland #endif 6385c51f124SMoriah Waterland 6395c51f124SMoriah Waterland if ((scr_fp = fopen(script_path, "r")) == NULL) { 6405c51f124SMoriah Waterland logerr(gettext(ERR_FOPEN), script_path, errno); 6415c51f124SMoriah Waterland return (0); 6425c51f124SMoriah Waterland } 6435c51f124SMoriah Waterland 6445c51f124SMoriah Waterland #ifdef VERBOSE 645*24e7a8c7SPaul Wernau printf("Opened script\n"); 6465c51f124SMoriah Waterland #endif 6475c51f124SMoriah Waterland 6485c51f124SMoriah Waterland while (val = yylex()) { 6495c51f124SMoriah Waterland #ifdef VERBOSE 6505c51f124SMoriah Waterland printf(" Match is %s, returned 0x%x at line %d\n", 6515c51f124SMoriah Waterland yytext, val, line_no); 6525c51f124SMoriah Waterland printf(" in_function = %d, in_awk = %d, in_loop = %d, " \ 6535c51f124SMoriah Waterland "in_case = %d, in_if = %d, in_pipe = %d\n", 6545c51f124SMoriah Waterland status.in_function, status.in_awk, status.in_loop, 6555c51f124SMoriah Waterland status.in_case, status.in_if, status.in_pipe); 6565c51f124SMoriah Waterland printf(" loop_depth = %d, case_depth = %d, " \ 6575c51f124SMoriah Waterland "if_depth = %d, pipe_release = %d, cur_level = %d\n", 6585c51f124SMoriah Waterland loop_depth, case_depth, if_depth, pipe_release, cur_level); 6595c51f124SMoriah Waterland #endif 6605c51f124SMoriah Waterland 6615c51f124SMoriah Waterland val &= mask; 6625c51f124SMoriah Waterland if (val) { 6635c51f124SMoriah Waterland error |= ((val & MAYBE_ONLY) ? 1 : 2); 6645c51f124SMoriah Waterland 6655c51f124SMoriah Waterland /* 6665c51f124SMoriah Waterland * So at this point, val contains all status bits 6675c51f124SMoriah Waterland * appropriate to this script. 6685c51f124SMoriah Waterland */ 6695c51f124SMoriah Waterland if (!silent) { 6705c51f124SMoriah Waterland char *msg_ptr; 6715c51f124SMoriah Waterland if (val & INTERACT_D) 6725c51f124SMoriah Waterland msg_ptr = gettext(ERR_INTERACT); 6735c51f124SMoriah Waterland else if (val & ROOT_D) 6745c51f124SMoriah Waterland msg_ptr = gettext(ERR_ROOT); 6755c51f124SMoriah Waterland else if (val & LOCKED_D) 6765c51f124SMoriah Waterland msg_ptr = gettext(ERR_LOCKED); 6775c51f124SMoriah Waterland else if (val & INTERACT_M) 6785c51f124SMoriah Waterland msg_ptr = gettext(WRN_INTERACT); 6795c51f124SMoriah Waterland else if (val & ROOT_M) 6805c51f124SMoriah Waterland msg_ptr = gettext(WRN_ROOT); 6815c51f124SMoriah Waterland else if (val & LOCKED_M) 6825c51f124SMoriah Waterland msg_ptr = gettext(WRN_LOCKED); 6835c51f124SMoriah Waterland else if (val & WPARM1_M) 6845c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_USE); 6855c51f124SMoriah Waterland else if (val & USEPARM1_M) 6865c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_USE); 6875c51f124SMoriah Waterland else if (val & ODDPARM_M) 6885c51f124SMoriah Waterland msg_ptr = gettext(WRN_FORM_ARG); 6895c51f124SMoriah Waterland else if (val & PKGDB_M) 6905c51f124SMoriah Waterland msg_ptr = gettext(WRN_TRANSDB); 6915c51f124SMoriah Waterland else 6925c51f124SMoriah Waterland msg_ptr = gettext("unknown error"); 6935c51f124SMoriah Waterland 6945c51f124SMoriah Waterland logerr(msg_ptr, script_name, line_no); 6955c51f124SMoriah Waterland } 6965c51f124SMoriah Waterland } 6975c51f124SMoriah Waterland } 6985c51f124SMoriah Waterland 6995c51f124SMoriah Waterland /* Warn if required about missing "-f" calls. */ 7005c51f124SMoriah Waterland if (status.instf && !(status.instf_f)) 7015c51f124SMoriah Waterland logerr(gettext(WRN_INST_F), script_name); 7025c51f124SMoriah Waterland 7035c51f124SMoriah Waterland if (status.remf && !(status.remf_f)) 7045c51f124SMoriah Waterland logerr(gettext(WRN_REM_F), script_name); 7055c51f124SMoriah Waterland 7065c51f124SMoriah Waterland status.instf = status.instf_f = status.remf = status.remf_f = 0; 7075c51f124SMoriah Waterland 7085c51f124SMoriah Waterland /* Warn if installf was used but no space file is in place. */ 7095c51f124SMoriah Waterland if (status.nospacefile && status.needspacefile) { 7105c51f124SMoriah Waterland logerr(gettext(WRN_SPACEACC), script_name); 7115c51f124SMoriah Waterland status.needspacefile = 0; 7125c51f124SMoriah Waterland } 7135c51f124SMoriah Waterland 7145c51f124SMoriah Waterland status.in_pipe = 0; /* Pipes may dangle. */ 7155c51f124SMoriah Waterland fclose(scr_fp); 7165c51f124SMoriah Waterland 7175c51f124SMoriah Waterland if (error == 3) 7185c51f124SMoriah Waterland error = 2; 7195c51f124SMoriah Waterland 7205c51f124SMoriah Waterland return (error); 7215c51f124SMoriah Waterland } 7225c51f124SMoriah Waterland 7235c51f124SMoriah Waterland /* Test a preinstall or preremove script for validity. */ 7245c51f124SMoriah Waterland int 7255c51f124SMoriah Waterland pre_valid(char *script_name, char *script_path, int silent) 7265c51f124SMoriah Waterland { 7275c51f124SMoriah Waterland return (scripteval(script_name, script_path, PRE_MASK, silent)); 7285c51f124SMoriah Waterland } 7295c51f124SMoriah Waterland 7305c51f124SMoriah Waterland /* Test a class action script for validity. */ 7315c51f124SMoriah Waterland int 7325c51f124SMoriah Waterland cas_valid(char *script_name, char *script_path, int silent) 7335c51f124SMoriah Waterland { 7345c51f124SMoriah Waterland return (scripteval(script_name, script_path, CAS_MASK, silent)); 7355c51f124SMoriah Waterland } 7365c51f124SMoriah Waterland 7375c51f124SMoriah Waterland /* Test a postinstall or postremove script for validity. */ 7385c51f124SMoriah Waterland int 7395c51f124SMoriah Waterland post_valid(char *script_name, char *script_path, int silent) 7405c51f124SMoriah Waterland { 7415c51f124SMoriah Waterland return (scripteval(script_name, script_path, POST_MASK, silent)); 7425c51f124SMoriah Waterland } 7435c51f124SMoriah Waterland 7445c51f124SMoriah Waterland /* Test a class action script for validity. */ 7455c51f124SMoriah Waterland int 7465c51f124SMoriah Waterland req_valid(char *script_name, char *script_path, int silent) 7475c51f124SMoriah Waterland { 7485c51f124SMoriah Waterland return (scripteval(script_name, script_path, REQ_MASK, silent)); 7495c51f124SMoriah Waterland } 7505c51f124SMoriah Waterland 7515c51f124SMoriah Waterland 7525c51f124SMoriah Waterland /* Test a class action script for validity. */ 7535c51f124SMoriah Waterland int 7545c51f124SMoriah Waterland chk_valid(char *script_name, char *script_path, int silent) 7555c51f124SMoriah Waterland { 7565c51f124SMoriah Waterland return (scripteval(script_name, script_path, CHK_MASK, silent)); 7575c51f124SMoriah Waterland } 7585c51f124SMoriah Waterland 7595c51f124SMoriah Waterland /* This tests all of the scripts in the provided directory. */ 7605c51f124SMoriah Waterland int 7615c51f124SMoriah Waterland checkscripts(char *inst_dir, int silent) 7625c51f124SMoriah Waterland { 7635c51f124SMoriah Waterland DIR *dirfp; 7645c51f124SMoriah Waterland struct dirent *dp; 7655c51f124SMoriah Waterland char path[PATH_MAX]; 7665c51f124SMoriah Waterland int retval = 0; 7675c51f124SMoriah Waterland 7685c51f124SMoriah Waterland /* For future reference, determine if a space file is present. */ 7695c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, "space"); 7705c51f124SMoriah Waterland if (access(path, F_OK) != 0) 7715c51f124SMoriah Waterland status.nospacefile = 1; 7725c51f124SMoriah Waterland 7735c51f124SMoriah Waterland if ((dirfp = opendir(inst_dir)) == NULL) 7745c51f124SMoriah Waterland return (0); 7755c51f124SMoriah Waterland 7765c51f124SMoriah Waterland while ((dp = readdir(dirfp)) != NULL) { 7775c51f124SMoriah Waterland #ifdef VERBOSE 7785c51f124SMoriah Waterland printf("Looking at file %s\n", dp->d_name); 7795c51f124SMoriah Waterland #endif 780*24e7a8c7SPaul Wernau #ifdef BUG_DEBUG 781*24e7a8c7SPaul Wernau if ((status.in_function != 0) 782*24e7a8c7SPaul Wernau || (status.in_pipe != 0) 783*24e7a8c7SPaul Wernau || (status.in_loop != 0) 784*24e7a8c7SPaul Wernau || (status.in_case != 0) 785*24e7a8c7SPaul Wernau || (status.in_if != 0) 786*24e7a8c7SPaul Wernau || (status.in_awk != 0) 787*24e7a8c7SPaul Wernau || (pipe_release != 0) 788*24e7a8c7SPaul Wernau || (loop_depth != 0) 789*24e7a8c7SPaul Wernau || (case_depth != 0) 790*24e7a8c7SPaul Wernau || (if_depth != 0) 791*24e7a8c7SPaul Wernau || (cur_level != 0) 792*24e7a8c7SPaul Wernau || (braces != 0)) { 793*24e7a8c7SPaul Wernau printf(" in_function = %d, in_awk = %d, " 794*24e7a8c7SPaul Wernau "in_loop = %d, in_case = %d, in_if = %d, " 795*24e7a8c7SPaul Wernau "in_pipe = %d\n", 796*24e7a8c7SPaul Wernau status.in_function, status.in_awk, status.in_loop, 797*24e7a8c7SPaul Wernau status.in_case, status.in_if, status.in_pipe); 798*24e7a8c7SPaul Wernau printf(" loop_depth = %d, case_depth = %d, " 799*24e7a8c7SPaul Wernau "if_depth = %d, pipe_release = %d, " 800*24e7a8c7SPaul Wernau "cur_level = %d\n", 801*24e7a8c7SPaul Wernau loop_depth, case_depth, if_depth, pipe_release, 802*24e7a8c7SPaul Wernau cur_level); 803*24e7a8c7SPaul Wernau printf("ERROR: found a bug: variable still open\n"); 804*24e7a8c7SPaul Wernau return (0); 805*24e7a8c7SPaul Wernau } else { 806*24e7a8c7SPaul Wernau printf("SUCCESS: All variables reset.\n"); 807*24e7a8c7SPaul Wernau } 808*24e7a8c7SPaul Wernau #endif 809*24e7a8c7SPaul Wernau /* Reset all variables before processing the next file */ 810*24e7a8c7SPaul Wernau status.in_function = status.in_pipe = status.in_loop = 811*24e7a8c7SPaul Wernau status.in_case = status.in_if = status.in_awk = 0; 812*24e7a8c7SPaul Wernau pipe_release = loop_depth = case_depth = if_depth = 813*24e7a8c7SPaul Wernau cur_level = braces = 0; 814*24e7a8c7SPaul Wernau 8155c51f124SMoriah Waterland if (dp->d_name[0] == '.') 8165c51f124SMoriah Waterland continue; 8175c51f124SMoriah Waterland 8185c51f124SMoriah Waterland if ((strcmp(dp->d_name, "preinstall") == 0) || 8195c51f124SMoriah Waterland (strcmp(dp->d_name, "preremove") == 0)) { 8205c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 8215c51f124SMoriah Waterland retval |= pre_valid(dp->d_name, path, silent); 8225c51f124SMoriah Waterland continue; 8235c51f124SMoriah Waterland } 8245c51f124SMoriah Waterland 8255c51f124SMoriah Waterland if ((strncmp(dp->d_name, "i.", 2) == 0) || 8265c51f124SMoriah Waterland (strncmp(dp->d_name, "r.", 2) == 0)) { 8275c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 8285c51f124SMoriah Waterland retval |= cas_valid(dp->d_name, path, silent); 8295c51f124SMoriah Waterland continue; 8305c51f124SMoriah Waterland } 8315c51f124SMoriah Waterland 8325c51f124SMoriah Waterland if ((strcmp(dp->d_name, "postinstall") == 0) || 8335c51f124SMoriah Waterland (strcmp(dp->d_name, "postremove") == 0)) { 8345c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 8355c51f124SMoriah Waterland retval |= post_valid(dp->d_name, path, silent); 8365c51f124SMoriah Waterland continue; 8375c51f124SMoriah Waterland } 8385c51f124SMoriah Waterland 8395c51f124SMoriah Waterland if (strcmp(dp->d_name, "request") == 0) { 8405c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 8415c51f124SMoriah Waterland retval |= req_valid(dp->d_name, path, silent); 8425c51f124SMoriah Waterland continue; 8435c51f124SMoriah Waterland } 8445c51f124SMoriah Waterland if (strcmp(dp->d_name, "checkinstall") == 0) { 8455c51f124SMoriah Waterland sprintf(path, "%s/%s", inst_dir, dp->d_name); 8465c51f124SMoriah Waterland retval |= chk_valid(dp->d_name, path, silent); 8475c51f124SMoriah Waterland continue; 8485c51f124SMoriah Waterland } 8495c51f124SMoriah Waterland } 8505c51f124SMoriah Waterland 8515c51f124SMoriah Waterland (void) closedir(dirfp); 8525c51f124SMoriah Waterland 8535c51f124SMoriah Waterland return (retval); 8545c51f124SMoriah Waterland } 855