Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/modutils/modprobe.c

    r902 r1765  
    1212*/
    1313
    14 #include "busybox.h"
     14#include "libbb.h"
    1515#include <sys/utsname.h>
    16 #include <sys/types.h>
    17 #include <sys/wait.h>
    18 #include <getopt.h>
    19 #include <stdlib.h>
    20 #include <unistd.h>
    21 #include <syslog.h>
    22 #include <string.h>
    23 #include <ctype.h>
    24 #include <fcntl.h>
    2516#include <fnmatch.h>
    2617
     
    3223struct dep_t {  /* one-way list of dependency rules */
    3324    /* a dependency rule */
    34     char *  m_name;             /* the module name*/
    35     char *  m_path;             /* the module file path */
    36     struct mod_opt_t *  m_options;  /* the module options */
    37 
    38     int     m_isalias  : 1;         /* the module is an alias */
    39     int     m_reserved : 15;        /* stuffin' */
    40 
    41     int     m_depcnt   : 16;        /* the number of dependable module(s) */
    42     char ** m_deparr;           /* the list of dependable module(s) */
    43 
    44     struct dep_t * m_next;          /* the next dependency rule */
     25    char *  m_name;                         /* the module name*/
     26    char *  m_path;                         /* the module file path */
     27    struct mod_opt_t *  m_options;          /* the module options */
     28
     29    int     m_isalias  : 1;                 /* the module is an alias */
     30    int     m_reserved : 15;                /* stuffin' */
     31
     32    int     m_depcnt   : 16;                /* the number of dependable module(s) */
     33    char ** m_deparr;                       /* the list of dependable module(s) */
     34
     35    struct dep_t * m_next;                  /* the next dependency rule */
    4536};
    4637
    4738struct mod_list_t { /* two-way list of modules to process */
    4839    /* a module description */
    49     char * m_name;
    50     char *  m_path;
    51     struct mod_opt_t *  m_options;
     40    const char * m_name;
     41    char * m_path;
     42    struct mod_opt_t * m_options;
    5243
    5344    struct mod_list_t * m_prev;
     
    8273static int main_opts;
    8374
    84 static int parse_tag_value ( char *buffer, char **ptag, char **pvalue )
     75static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
    8576{
    8677    char *tag, *value;
    8778
    88     while ( isspace ( *buffer ))
    89         buffer++;
     79    buffer = skip_whitespace(buffer);
    9080    tag = value = buffer;
    91     while ( !isspace ( *value ))
     81    while (!isspace(*value))
    9282        if (!*value) return 0;
    9383        else value++;
    9484    *value++ = 0;
    95     while ( isspace ( *value ))
    96         value++;
     85    value = skip_whitespace(value);
    9786    if (!*value) return 0;
    9887
     
    10190
    10291    return 1;
    103 }
    104 
    105 /* Jump through hoops to simulate how fgets() grabs just one line at a
    106  * time... Don't use any stdio since modprobe gets called from a kernel
    107  * thread and stdio junk can overflow the limited stack...
    108  */
    109 static char *reads ( int fd, char *buffer, size_t len )
    110 {
    111     int n = read ( fd, buffer, len );
    112 
    113     if ( n > 0 ) {
    114         char *p;
    115 
    116         buffer [len-1] = 0;
    117         p = strchr ( buffer, '\n' );
    118 
    119         if ( p ) {
    120             off_t offset;
    121 
    122             offset = lseek ( fd, 0L, SEEK_CUR );               // Get the current file descriptor offset
    123             lseek ( fd, offset-n + (p-buffer) + 1, SEEK_SET ); // Set the file descriptor offset to right after the \n
    124 
    125             p[1] = 0;
    126         }
    127         return buffer;
    128     }
    129 
    130     else
    131         return 0;
    13292}
    13393
     
    13595 * This function appends an option to a list
    13696 */
    137 static struct mod_opt_t *append_option( struct mod_opt_t *opt_list, char *opt )
     97static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt)
    13898{
    13999    struct mod_opt_t *ol = opt_list;
    140100
    141     if( ol ) {
    142         while( ol-> m_next ) {
    143             ol = ol-> m_next;
    144         }
    145         ol-> m_next = xmalloc( sizeof( struct mod_opt_t ) );
    146         ol = ol-> m_next;
     101    if (ol) {
     102        while (ol->m_next) {
     103            ol = ol->m_next;
     104        }
     105        ol->m_next = xmalloc(sizeof(struct mod_opt_t));
     106        ol = ol->m_next;
    147107    } else {
    148         ol = opt_list = xmalloc( sizeof( struct mod_opt_t ) );
    149     }
    150 
    151     ol-> m_opt_val = bb_xstrdup( opt );
    152     ol-> m_next = NULL;
     108        ol = opt_list = xmalloc(sizeof(struct mod_opt_t));
     109    }
     110
     111    ol->m_opt_val = xstrdup(opt);
     112    ol->m_next = NULL;
    153113
    154114    return opt_list;
     
    156116
    157117#if ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS
    158 /* static char* parse_command_string( char* src, char **dst );
     118/* static char* parse_command_string(char* src, char **dst);
    159119 *   src: pointer to string containing argument
    160120 *   dst: pointer to where to store the parsed argument
    161121 *   return value: the pointer to the first char after the parsed argument,
    162122 *                 NULL if there was no argument parsed (only trailing spaces).
    163  *   Note that memory is allocated with bb_xstrdup when a new argument was
     123 *   Note that memory is allocated with xstrdup when a new argument was
    164124 *   parsed. Don't forget to free it!
    165125 */
     
    167127#define ARG_IN_DQUOTES 0x01
    168128#define ARG_IN_SQUOTES 0x02
    169 static char *parse_command_string( char *src, char **dst )
     129static char *parse_command_string(char *src, char **dst)
    170130{
    171131    int opt_status = ARG_EMPTY;
     
    173133
    174134    /* Dumb you, I have nothing to do... */
    175     if( src == NULL ) return src;
     135    if (src == NULL) return src;
    176136
    177137    /* Skip leading spaces */
    178     while( *src == ' ' ) {
     138    while (*src == ' ') {
    179139        src++;
    180140    }
    181141    /* Is the end of string reached? */
    182     if( *src == '\0' ) {
     142    if (*src == '\0') {
    183143        return NULL;
    184144    }
     
    186146     * By the way, we duplicate a little too much
    187147     * here but what is too much is freed later. */
    188     *dst = tmp_str = bb_xstrdup( src );
     148    *dst = tmp_str = xstrdup(src);
    189149    /* Get to the end of that argument */
    190     while(    ( *tmp_str != '\0' )
    191            && (    ( *tmp_str != ' ' )
    192             || ( opt_status & ( ARG_IN_DQUOTES | ARG_IN_SQUOTES ) ) ) ) {
    193         switch( *tmp_str ) {
    194             case '\'':
    195                 if( opt_status & ARG_IN_DQUOTES ) {
    196                     /* Already in double quotes, keep current char as is */
    197                 } else {
    198                     /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
    199                     memmove( tmp_str, tmp_str + 1, strlen( tmp_str ) );
    200                     /* mark me: we enter or leave single quotes */
    201                     opt_status ^= ARG_IN_SQUOTES;
    202                     /* Back one char, as we need to re-scan the new char there. */
    203                     tmp_str--;
    204                 }
     150    while (*tmp_str != '\0'
     151     && (*tmp_str != ' ' || (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)))
     152    ) {
     153        switch (*tmp_str) {
     154        case '\'':
     155            if (opt_status & ARG_IN_DQUOTES) {
     156                /* Already in double quotes, keep current char as is */
     157            } else {
     158                /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
     159                memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
     160                /* mark me: we enter or leave single quotes */
     161                opt_status ^= ARG_IN_SQUOTES;
     162                /* Back one char, as we need to re-scan the new char there. */
     163                tmp_str--;
     164            }
    205165            break;
    206             case '"':
    207                 if( opt_status & ARG_IN_SQUOTES ) {
    208                     /* Already in single quotes, keep current char as is */
    209                 } else {
    210                     /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
    211                     memmove( tmp_str, tmp_str + 1, strlen( tmp_str ) );
    212                     /* mark me: we enter or leave double quotes */
    213                     opt_status ^= ARG_IN_DQUOTES;
    214                     /* Back one char, as we need to re-scan the new char there. */
    215                     tmp_str--;
    216                 }
     166        case '"':
     167            if (opt_status & ARG_IN_SQUOTES) {
     168                /* Already in single quotes, keep current char as is */
     169            } else {
     170                /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
     171                memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
     172                /* mark me: we enter or leave double quotes */
     173                opt_status ^= ARG_IN_DQUOTES;
     174                /* Back one char, as we need to re-scan the new char there. */
     175                tmp_str--;
     176            }
    217177            break;
    218             case '\\':
    219                 if( opt_status & ARG_IN_SQUOTES ) {
    220                     /* Between single quotes: keep as is. */
    221                 } else {
    222                     switch( *(tmp_str+1) ) {
    223                         case 'a':
    224                         case 'b':
    225                         case 't':
    226                         case 'n':
    227                         case 'v':
    228                         case 'f':
    229                         case 'r':
    230                         case '0':
    231                             /* We escaped a special character. For now, keep
    232                             * both the back-slash and the following char. */
    233                             tmp_str++; src++;
    234                             break;
    235                         default:
    236                             /* We escaped a space or a single or double quote,
    237                             * or a back-slash, or a non-escapable char. Remove
    238                             * the '\' and keep the new current char as is. */
    239                             memmove( tmp_str, tmp_str + 1, strlen( tmp_str ) );
    240                             break;
    241                     }
    242                 }
     178        case '\\':
     179            if (opt_status & ARG_IN_SQUOTES) {
     180                /* Between single quotes: keep as is. */
     181            } else {
     182                switch (*(tmp_str+1)) {
     183                case 'a':
     184                case 'b':
     185                case 't':
     186                case 'n':
     187                case 'v':
     188                case 'f':
     189                case 'r':
     190                case '0':
     191                    /* We escaped a special character. For now, keep
     192                    * both the back-slash and the following char. */
     193                    tmp_str++; src++;
     194                    break;
     195                default:
     196                    /* We escaped a space or a single or double quote,
     197                    * or a back-slash, or a non-escapable char. Remove
     198                    * the '\' and keep the new current char as is. */
     199                    memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
     200                    break;
     201                }
     202            }
    243203            break;
    244             /* Any other char that is special shall appear here.
    245             * Example: $ starts a variable
    246             case '$':
    247                 do_variable_expansion();
    248                 break;
    249             * */
    250             default:
    251                 /* any other char is kept as is. */
    252                 break;
     204        /* Any other char that is special shall appear here.
     205        * Example: $ starts a variable
     206        case '$':
     207            do_variable_expansion();
     208            break;
     209        * */
     210        default:
     211            /* any other char is kept as is. */
     212            break;
    253213        }
    254214        tmp_str++; /* Go to next char */
     
    256216    }
    257217    /* End of string, but still no ending quote */
    258     if( opt_status & ( ARG_IN_DQUOTES | ARG_IN_SQUOTES ) ) {
    259         bb_error_msg_and_die( "unterminated (single or double) quote in options list: %s", src );
     218    if (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)) {
     219        bb_error_msg_and_die("unterminated (single or double) quote in options list: %s", src);
    260220    }
    261221    *tmp_str++ = '\0';
    262     *dst = xrealloc( *dst, (tmp_str - *dst ) );
     222    *dst = xrealloc(*dst, (tmp_str - *dst));
    263223    return src;
    264224}
     
    271231 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
    272232 */
    273 static void include_conf ( struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd )
     233static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd)
    274234{
    275235    int continuation_line = 0;
    276236
    277     // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) !
    278 
    279     while ( reads ( fd, buffer, buflen)) {
     237    // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)!
     238
     239    while (reads(fd, buffer, buflen)) {
    280240        int l;
    281241        char *p;
    282242
    283         p = strchr ( buffer, '#' );
    284         if ( p )
     243        p = strchr(buffer, '#');
     244        if (p)
    285245            *p = 0;
    286246
    287         l = strlen ( buffer );
    288 
    289         while ( l && isspace ( buffer [l-1] )) {
    290             buffer [l-1] = 0;
     247        l = strlen(buffer);
     248
     249        while (l && isspace(buffer[l-1])) {
     250            buffer[l-1] = 0;
    291251            l--;
    292252        }
    293253
    294         if ( l == 0 ) {
     254        if (l == 0) {
    295255            continuation_line = 0;
    296256            continue;
    297257        }
    298258
    299         if ( !continuation_line ) {
    300             if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) {
     259        if (!continuation_line) {
     260            if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
    301261                char *alias, *mod;
    302262
    303                 if ( parse_tag_value ( buffer + 6, &alias, &mod )) {
     263                if (parse_tag_value(buffer + 6, &alias, &mod)) {
    304264                    /* handle alias as a module dependent on the aliased module */
    305                     if ( !*current ) {
    306                         (*first) = (*current) = (struct dep_t *) xcalloc ( 1, sizeof ( struct dep_t ));
     265                    if (!*current) {
     266                        (*first) = (*current) = xzalloc(sizeof(struct dep_t));
     267                    } else {
     268                        (*current)->m_next = xzalloc(sizeof(struct dep_t));
     269                        (*current) = (*current)->m_next;
    307270                    }
    308                     else {
    309                         (*current)-> m_next = (struct dep_t *) xcalloc ( 1, sizeof ( struct dep_t ));
    310                         (*current) = (*current)-> m_next;
     271                    (*current)->m_name  = xstrdup(alias);
     272                    (*current)->m_isalias = 1;
     273
     274                    if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) {
     275                        (*current)->m_depcnt = 0;
     276                        (*current)->m_deparr = 0;
     277                    } else {
     278                        (*current)->m_depcnt  = 1;
     279                        (*current)->m_deparr  = xmalloc(1 * sizeof(char *));
     280                        (*current)->m_deparr[0] = xstrdup(mod);
    311281                    }
    312                     (*current)-> m_name  = bb_xstrdup ( alias );
    313                     (*current)-> m_isalias = 1;
    314 
    315                     if (( strcmp ( mod, "off" ) == 0 ) || ( strcmp ( mod, "null" ) == 0 )) {
    316                         (*current)-> m_depcnt = 0;
    317                         (*current)-> m_deparr = 0;
    318                     }
    319                     else {
    320                         (*current)-> m_depcnt  = 1;
    321                         (*current)-> m_deparr  = xmalloc ( 1 * sizeof( char * ));
    322                         (*current)-> m_deparr[0] = bb_xstrdup ( mod );
    323                     }
    324                     (*current)-> m_next    = 0;
    325                 }
    326             }
    327             else if (( strncmp ( buffer, "options", 7 ) == 0 ) && isspace ( buffer [7] )) {
     282                    (*current)->m_next    = 0;
     283                }
     284            } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
    328285                char *mod, *opt;
    329286
    330287                /* split the line in the module/alias name, and options */
    331                 if ( parse_tag_value ( buffer + 8, &mod, &opt )) {
     288                if (parse_tag_value(buffer + 8, &mod, &opt)) {
    332289                    struct dep_t *dt;
    333290
    334291                    /* find the corresponding module */
    335                     for ( dt = *first; dt; dt = dt-> m_next ) {
    336                         if ( strcmp ( dt-> m_name, mod ) == 0 )
     292                    for (dt = *first; dt; dt = dt->m_next) {
     293                        if (strcmp(dt->m_name, mod) == 0)
    337294                            break;
    338295                    }
    339                     if ( dt ) {
    340                         if ( ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS ) {
     296                    if (dt) {
     297                        if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) {
    341298                            char* new_opt = NULL;
    342                             while( ( opt = parse_command_string( opt, &new_opt ) ) ) {
    343                                 dt-> m_options = append_option( dt-> m_options, new_opt );
     299                            while ((opt = parse_command_string(opt, &new_opt))) {
     300                                dt->m_options = append_option(dt->m_options, new_opt);
    344301                            }
    345302                        } else {
    346                             dt-> m_options = append_option( dt-> m_options, opt );
     303                            dt->m_options = append_option(dt->m_options, opt);
    347304                        }
    348305                    }
    349306                }
    350             }
    351             else if (( strncmp ( buffer, "include", 7 ) == 0 ) && isspace ( buffer [7] )) {
    352 
    353                 int fdi; char *filename = buffer + 8;
    354 
    355                 while ( isspace ( *filename ))
    356                     filename++;
    357 
    358                 if (( fdi = open ( filename, O_RDONLY )) >= 0 ) {
     307            } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
     308                int fdi; char *filename;
     309
     310                filename = skip_whitespace(buffer + 8);
     311
     312                if ((fdi = open(filename, O_RDONLY)) >= 0) {
    359313                    include_conf(first, current, buffer, buflen, fdi);
    360314                    close(fdi);
     
    366320
    367321/*
    368  * This function builds a list of dependency rules from /lib/modules/`uname -r`\modules.dep.
     322 * This function builds a list of dependency rules from /lib/modules/`uname -r`/modules.dep.
    369323 * It then fills every modules and aliases with their default options, found by parsing
    370324 * modprobe.conf (or modules.conf, or conf.modules).
    371325 */
    372 static struct dep_t *build_dep ( void )
     326static struct dep_t *build_dep(void)
    373327{
    374328    int fd;
     
    381335    int k_version;
    382336
     337    if (uname(&un))
     338        bb_error_msg_and_die("can't determine kernel version");
     339
    383340    k_version = 0;
    384     if ( uname ( &un ))
    385         bb_error_msg_and_die("can't determine kernel version");
    386 
    387341    if (un.release[0] == '2') {
    388342        k_version = un.release[2] - '0';
    389343    }
    390344
    391     filename = bb_xasprintf("/lib/modules/%s/modules.dep", un.release );
    392     fd = open ( filename, O_RDONLY );
     345    filename = xasprintf("/lib/modules/%s/modules.dep", un.release);
     346    fd = open(filename, O_RDONLY);
    393347    if (ENABLE_FEATURE_CLEAN_UP)
    394348        free(filename);
    395349    if (fd < 0) {
    396350        /* Ok, that didn't work.  Fall back to looking in /lib/modules */
    397         if (( fd = open ( "/lib/modules/modules.dep", O_RDONLY )) < 0 ) {
     351        fd = open("/lib/modules/modules.dep", O_RDONLY);
     352        if (fd < 0) {
    398353            return 0;
    399354        }
    400355    }
    401356
    402     while ( reads ( fd, buffer, sizeof( buffer ))) {
    403         int l = strlen ( buffer );
     357    while (reads(fd, buffer, sizeof(buffer))) {
     358        int l = strlen(buffer);
    404359        char *p = 0;
    405360
    406         while ( l > 0 && isspace ( buffer [l-1] )) {
    407             buffer [l-1] = 0;
     361        while (l > 0 && isspace(buffer[l-1])) {
     362            buffer[l-1] = 0;
    408363            l--;
    409364        }
    410365
    411         if ( l == 0 ) {
     366        if (l == 0) {
    412367            continuation_line = 0;
    413368            continue;
     
    415370
    416371        /* Is this a new module dep description? */
    417         if ( !continuation_line ) {
     372        if (!continuation_line) {
    418373            /* find the dep beginning */
    419             char *col = strchr ( buffer, ':' );
     374            char *col = strchr(buffer, ':');
    420375            char *dot = col;
    421376
    422             if ( col ) {
     377            if (col) {
    423378                /* This line is a dep description */
    424                 char *mods;
     379                const char *mods;
    425380                char *modpath;
    426381                char *mod;
     
    428383                /* Find the beginning of the module file name */
    429384                *col = 0;
    430                 mods = strrchr ( buffer, '/' );
    431 
    432                 if ( !mods )
    433                     mods = buffer; /* no path for this module */
    434                 else
    435                     mods++; /* there was a path for this module... */
     385                mods = bb_basename(buffer);
    436386
    437387                /* find the path of the module */
    438                 modpath = strchr ( buffer, '/' ); /* ... and this is the path */
    439                 if ( !modpath )
     388                modpath = strchr(buffer, '/'); /* ... and this is the path */
     389                if (!modpath)
    440390                    modpath = buffer; /* module with no path */
    441391                /* find the end of the module name in the file name */
    442                 if ( ENABLE_FEATURE_2_6_MODULES &&
    443                      (k_version > 4) && ( *(col-3) == '.' ) &&
    444                      ( *(col-2) == 'k' ) && ( *(col-1) == 'o' ) )
     392                if (ENABLE_FEATURE_2_6_MODULES &&
     393                     (k_version > 4) && (*(col-3) == '.') &&
     394                    (*(col-2) == 'k') && (*(col-1) == 'o'))
    445395                    dot = col - 3;
    446396                else
    447                     if (( *(col-2) == '.' ) && ( *(col-1) == 'o' ))
     397                    if ((*(col-2) == '.') && (*(col-1) == 'o'))
    448398                        dot = col - 2;
    449399
    450                 mod = bb_xstrndup ( mods, dot - mods );
     400                mod = xstrndup(mods, dot - mods);
    451401
    452402                /* enqueue new module */
    453                 if ( !current ) {
    454                     first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
    455                 }
    456                 else {
    457                     current-> m_next = (struct dep_t *) xmalloc ( sizeof ( struct dep_t ));
    458                     current = current-> m_next;
    459                 }
    460                 current-> m_name  = mod;
    461                 current-> m_path  = bb_xstrdup(modpath);
    462                 current-> m_options = NULL;
    463                 current-> m_isalias = 0;
    464                 current-> m_depcnt  = 0;
    465                 current-> m_deparr  = 0;
    466                 current-> m_next    = 0;
     403                if (!current) {
     404                    first = current = xmalloc(sizeof(struct dep_t));
     405                } else {
     406                    current->m_next = xmalloc(sizeof(struct dep_t));
     407                    current = current->m_next;
     408                }
     409                current->m_name    = mod;
     410                current->m_path    = xstrdup(modpath);
     411                current->m_options = NULL;
     412                current->m_isalias = 0;
     413                current->m_depcnt  = 0;
     414                current->m_deparr  = 0;
     415                current->m_next    = 0;
    467416
    468417                p = col + 1;
    469             }
    470             else
     418            } else
    471419                /* this line is not a dep description */
    472420                p = 0;
    473         }
    474         else
     421        } else
    475422            /* It's a dep description continuation */
    476423            p = buffer;
    477424
    478         while ( p && *p && isblank(*p))
     425        while (p && *p && isblank(*p))
    479426            p++;
    480427
    481428        /* p points to the first dependable module; if NULL, no dependable module */
    482         if ( p && *p ) {
    483             char *end = &buffer [l-1];
    484             char *deps;
     429        if (p && *p) {
     430            char *end = &buffer[l-1];
     431            const char *deps;
    485432            char *dep;
    486433            char *next;
    487434            int ext = 0;
    488435
    489             while ( isblank ( *end ) || ( *end == '\\' ))
     436            while (isblank(*end) || (*end == '\\'))
    490437                end--;
    491438
    492             do
    493             {
     439            do {
    494440                /* search the end of the dependency */
    495                 next = strchr (p, ' ' );
    496                 if (next)
    497                 {
     441                next = strchr(p, ' ');
     442                if (next) {
    498443                    *next = 0;
    499444                    next--;
    500                 }
    501                 else
     445                } else
    502446                    next = end;
    503447
    504448                /* find the beginning of the module file name */
    505                 deps = strrchr ( p, '/' );
    506 
    507                 if ( !deps || ( deps < p )) {
    508                     deps = p;
    509 
    510                     while ( isblank ( *deps ))
     449                deps = bb_basename(p);
     450                if (deps == p) {
     451                    while (isblank(*deps))
    511452                        deps++;
    512453                }
    513                 else
    514                     deps++;
    515454
    516455                /* find the end of the module name in the file name */
    517                 if ( ENABLE_FEATURE_2_6_MODULES &&
    518                      (k_version > 4) && ( *(next-2) == '.' ) &&
    519                      ( *(next-1) == 'k' )  && ( *next == 'o' ) )
     456                if (ENABLE_FEATURE_2_6_MODULES
     457                 && (k_version > 4) && (*(next-2) == '.')
     458                 && (*(next-1) == 'k') && (*next == 'o'))
    520459                    ext = 3;
    521460                else
    522                     if (( *(next-1) == '.' ) && ( *next == 'o' ))
     461                    if ((*(next-1) == '.') && (*next == 'o'))
    523462                        ext = 2;
    524463
     
    526465                if ((next-deps-ext+1) <= 0)
    527466                    continue;
    528                 dep = bb_xstrndup ( deps, next - deps - ext + 1 );
     467                dep = xstrndup(deps, next - deps - ext + 1);
    529468
    530469                /* Add the new dependable module name */
    531                 current-> m_depcnt++;
    532                 current-> m_deparr = (char **) xrealloc ( current-> m_deparr,
    533                         sizeof ( char *) * current-> m_depcnt );
    534                 current-> m_deparr [current-> m_depcnt - 1] = dep;
     470                current->m_depcnt++;
     471                current->m_deparr = xrealloc(current->m_deparr,
     472                        sizeof(char *) * current->m_depcnt);
     473                current->m_deparr[current->m_depcnt - 1] = dep;
    535474
    536475                p = next + 2;
     
    539478
    540479        /* is there other dependable module(s) ? */
    541         if ( buffer [l-1] == '\\' )
     480        if (buffer[l-1] == '\\')
    542481            continuation_line = 1;
    543482        else
    544483            continuation_line = 0;
    545484    }
    546     close ( fd );
     485    close(fd);
    547486
    548487    /*
    549488     * First parse system-specific options and aliases
    550489     * as they take precedence over the kernel ones.
     490     * >=2.6: we only care about modprobe.conf
     491     * <=2.4: we care about modules.conf and conf.modules
    551492     */
    552     if (!ENABLE_FEATURE_2_6_MODULES
    553             || ( fd = open ( "/etc/modprobe.conf", O_RDONLY )) < 0 )
    554         if (( fd = open ( "/etc/modules.conf", O_RDONLY )) < 0 )
    555             fd = open ( "/etc/conf.modules", O_RDONLY );
     493    if (ENABLE_FEATURE_2_6_MODULES
     494     && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0)
     495        if (ENABLE_FEATURE_2_4_MODULES
     496         && (fd = open("/etc/modules.conf", O_RDONLY)) < 0)
     497            if (ENABLE_FEATURE_2_4_MODULES)
     498                fd = open("/etc/conf.modules", O_RDONLY);
    556499
    557500    if (fd >= 0) {
    558         include_conf (&first, &current, buffer, sizeof(buffer), fd);
     501        include_conf(&first, &current, buffer, sizeof(buffer), fd);
    559502        close(fd);
    560503    }
     
    562505    /* Only 2.6 has a modules.alias file */
    563506    if (ENABLE_FEATURE_2_6_MODULES) {
    564         /* Parse kernel-declared aliases */
    565         filename = bb_xasprintf("/lib/modules/%s/modules.alias", un.release);
    566         if ((fd = open ( filename, O_RDONLY )) < 0) {
     507        /* Parse kernel-declared module aliases */
     508        filename = xasprintf("/lib/modules/%s/modules.alias", un.release);
     509        fd = open(filename, O_RDONLY);
     510        if (fd < 0) {
    567511            /* Ok, that didn't work.  Fall back to looking in /lib/modules */
    568             fd = open ( "/lib/modules/modules.alias", O_RDONLY );
     512            fd = open("/lib/modules/modules.alias", O_RDONLY);
    569513        }
    570514        if (ENABLE_FEATURE_CLEAN_UP)
     
    572516
    573517        if (fd >= 0) {
    574             include_conf (&first, &current, buffer, sizeof(buffer), fd);
     518            include_conf(&first, &current, buffer, sizeof(buffer), fd);
    575519            close(fd);
    576520        }
     521
     522        /* Parse kernel-declared symbol aliases */
     523        filename = xasprintf("/lib/modules/%s/modules.symbols", un.release);
     524        fd = open(filename, O_RDONLY);
     525        if (fd < 0) {
     526            /* Ok, that didn't work.  Fall back to looking in /lib/modules */
     527            fd = open("/lib/modules/modules.symbols", O_RDONLY);
     528        }
     529        if (ENABLE_FEATURE_CLEAN_UP)
     530            free(filename);
     531
     532        if (fd >= 0) {
     533            include_conf(&first, &current, buffer, sizeof(buffer), fd);
     534            close(fd);
     535        }
    577536    }
    578537
     
    581540
    582541/* return 1 = loaded, 0 = not loaded, -1 = can't tell */
    583 static int already_loaded (const char *name)
     542static int already_loaded(const char *name)
    584543{
    585544    int fd, ret = 0;
    586545    char buffer[4096];
    587546
    588     fd = open ("/proc/modules", O_RDONLY);
     547    fd = open("/proc/modules", O_RDONLY);
    589548    if (fd < 0)
    590549        return -1;
    591550
    592     while ( reads ( fd, buffer, sizeof( buffer ))) {
     551    while (reads(fd, buffer, sizeof(buffer))) {
    593552        char *p;
    594553
     
    621580}
    622581
    623 static int mod_process ( struct mod_list_t *list, int do_insert )
     582static int mod_process(const struct mod_list_t *list, int do_insert)
    624583{
    625584    int rc = 0;
     
    629588    int argc;
    630589
    631     while ( list ) {
     590    while (list) {
    632591        argc = 0;
    633         if( ENABLE_FEATURE_CLEAN_UP )
     592        if (ENABLE_FEATURE_CLEAN_UP)
    634593            argc_malloc = 0;
    635594        /* If CONFIG_FEATURE_CLEAN_UP is not defined, then we leak memory
     
    644603         * problem. */
    645604        /* enough for minimal insmod (5 args + NULL) or rmmod (3 args + NULL) */
    646         argv = (char**) malloc( 6 * sizeof( char* ) );
    647         if ( do_insert ) {
    648             if (already_loaded (list->m_name) != 1) {
    649                 argv[argc++] = "insmod";
     605        argv = xmalloc(6 * sizeof(char*));
     606        if (do_insert) {
     607            if (already_loaded(list->m_name) != 1) {
     608                argv[argc++] = (char*)"insmod";
    650609                if (ENABLE_FEATURE_2_4_MODULES) {
    651610                    if (do_syslog)
    652                         argv[argc++] = "-s";
     611                        argv[argc++] = (char*)"-s";
    653612                    if (autoclean)
    654                         argv[argc++] = "-k";
     613                        argv[argc++] = (char*)"-k";
    655614                    if (quiet)
    656                         argv[argc++] = "-q";
    657                     else if(verbose) /* verbose and quiet are mutually exclusive */
    658                         argv[argc++] = "-v";
    659                 }
    660                 argv[argc++] = list-> m_path;
    661                 if( ENABLE_FEATURE_CLEAN_UP )
     615                        argv[argc++] = (char*)"-q";
     616                    else if (verbose) /* verbose and quiet are mutually exclusive */
     617                        argv[argc++] = (char*)"-v";
     618                }
     619                argv[argc++] = list->m_path;
     620                if (ENABLE_FEATURE_CLEAN_UP)
    662621                    argc_malloc = argc;
    663                 opts = list-> m_options;
    664                 while( opts ) {
     622                opts = list->m_options;
     623                while (opts) {
    665624                    /* Add one more option */
    666625                    argc++;
    667                     argv = (char**) xrealloc( argv, ( argc + 1 ) * sizeof( char* ) );
    668                     argv[argc-1] = opts-> m_opt_val;
    669                     opts = opts-> m_next;
     626                    argv = xrealloc(argv,(argc + 1)* sizeof(char*));
     627                    argv[argc-1] = opts->m_opt_val;
     628                    opts = opts->m_next;
    670629                }
    671630            }
    672631        } else {
    673632            /* modutils uses short name for removal */
    674             if (already_loaded (list->m_name) != 0) {
    675                 argv[argc++] = "rmmod";
     633            if (already_loaded(list->m_name) != 0) {
     634                argv[argc++] = (char*)"rmmod";
    676635                if (do_syslog)
    677                     argv[argc++] = "-s";
    678                 argv[argc++] = list->m_name;
    679                 if( ENABLE_FEATURE_CLEAN_UP )
     636                    argv[argc++] = (char*)"-s";
     637                argv[argc++] = (char*)list->m_name;
     638                if (ENABLE_FEATURE_CLEAN_UP)
    680639                    argc_malloc = argc;
    681640            }
     
    685644        if (argc) {
    686645            if (verbose) {
    687                 printf("%s module %s\n", do_insert?"Loading":"Unloading", list-> m_name );
     646                printf("%s module %s\n", do_insert?"Loading":"Unloading", list->m_name);
    688647            }
    689648            if (!show_only) {
    690                 int rc2 = wait4pid(bb_spawn(argv));
     649                int rc2 = wait4pid(spawn(argv));
    691650
    692651                if (do_insert) {
    693652                    rc = rc2; /* only last module matters */
    694                 }
    695                 else if (!rc2) {
     653                } else if (!rc2) {
    696654                    rc = 0; /* success if remove any mod */
    697655                }
    698656            }
    699             if( ENABLE_FEATURE_CLEAN_UP )
     657            if (ENABLE_FEATURE_CLEAN_UP) {
    700658                /* the last value in the array has index == argc, but
    701659                 * it is the terminating NULL, so we must not free it. */
    702                 while( argc_malloc < argc ) {
    703                     free( argv[argc_malloc++] );
    704             }
    705         }
    706         if( ENABLE_FEATURE_CLEAN_UP ) {
    707             free( argv );
     660                while (argc_malloc < argc) {
     661                    free(argv[argc_malloc++]);
     662                }
     663            }
     664        }
     665        if (ENABLE_FEATURE_CLEAN_UP) {
     666            free(argv);
    708667            argv = NULL;
    709668        }
    710         list = do_insert ? list-> m_prev : list-> m_next;
     669        list = do_insert ? list->m_prev : list->m_next;
    711670    }
    712671    return (show_only) ? 0 : rc;
     672}
     673
     674/*
     675 * Check the matching between a pattern and a module name.
     676 * We need this as *_* is equivalent to *-*, even in pattern matching.
     677 */
     678static int check_pattern(const char* pat_src, const char* mod_src)
     679{
     680    int ret;
     681
     682    if (ENABLE_FEATURE_MODPROBE_FANCY_ALIAS) {
     683        char* pat;
     684        char* mod;
     685        char* p;
     686
     687        pat = xstrdup(pat_src);
     688        mod = xstrdup(mod_src);
     689
     690        for (p = pat; (p = strchr(p, '-')); *p++ = '_');
     691        for (p = mod; (p = strchr(p, '-')); *p++ = '_');
     692
     693        ret = fnmatch(pat, mod, 0);
     694
     695        if (ENABLE_FEATURE_CLEAN_UP) {
     696            free(pat);
     697            free(mod);
     698        }
     699
     700        return ret;
     701    } else {
     702        return fnmatch(pat_src, mod_src, 0);
     703    }
    713704}
    714705
     
    718709 * tail: the lowest module in the stack (first to insmod, last to rmmod)
    719710 */
    720 static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t **tail )
     711static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **tail)
    721712{
    722713    struct mod_list_t *find;
     
    730721     * Of course if the name in the dependency rule is a plain string,
    731722     * then we consider it a pattern, and matching will still work. */
    732     for ( dt = depend; dt; dt = dt-> m_next ) {
    733         if ( fnmatch ( dt-> m_name, mod, 0 ) == 0) {
     723    for (dt = depend; dt; dt = dt->m_next) {
     724        if (check_pattern(dt->m_name, mod) == 0) {
    734725            break;
    735726        }
    736727    }
    737728
    738     if( !dt ) {
    739         bb_error_msg ("module %s not found.", mod);
     729    if (!dt) {
     730        bb_error_msg("module %s not found", mod);
    740731        return;
    741732    }
    742733
    743734    // resolve alias names
    744     while ( dt-> m_isalias ) {
    745         if ( dt-> m_depcnt == 1 ) {
     735    while (dt->m_isalias) {
     736        if (dt->m_depcnt == 1) {
    746737            struct dep_t *adt;
    747738
    748             for ( adt = depend; adt; adt = adt-> m_next ) {
    749                 if ( strcmp ( adt-> m_name, dt-> m_deparr [0] ) == 0 )
     739            for (adt = depend; adt; adt = adt->m_next) {
     740                if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0)
    750741                    break;
    751742            }
    752             if ( adt ) {
     743            if (adt) {
    753744                /* This is the module we are aliased to */
    754                 struct mod_opt_t *opts = dt-> m_options;
     745                struct mod_opt_t *opts = dt->m_options;
    755746                /* Option of the alias are appended to the options of the module */
    756                 while( opts ) {
    757                     adt-> m_options = append_option( adt-> m_options, opts-> m_opt_val );
    758                     opts = opts-> m_next;
     747                while (opts) {
     748                    adt->m_options = append_option(adt->m_options, opts->m_opt_val);
     749                    opts = opts->m_next;
    759750                }
    760751                dt = adt;
    761             }
    762             else {
    763                 bb_error_msg ("module %s not found.", mod);
     752            } else {
     753                bb_error_msg("module %s not found", mod);
    764754                return;
    765755            }
    766         }
    767         else {
    768             bb_error_msg ("Bad alias %s", dt-> m_name);
     756        } else {
     757            bb_error_msg("bad alias %s", dt->m_name);
    769758            return;
    770759        }
    771760    }
    772761
    773     mod = dt-> m_name;
    774     path = dt-> m_path;
    775     opt = dt-> m_options;
     762    mod = dt->m_name;
     763    path = dt->m_path;
     764    opt = dt->m_options;
    776765
    777766    // search for duplicates
    778     for ( find = *head; find; find = find-> m_next ) {
    779         if ( !strcmp ( mod, find-> m_name )) {
    780             // found -> dequeue it
    781 
    782             if ( find-> m_prev )
    783                 find-> m_prev-> m_next = find-> m_next;
     767    for (find = *head; find; find = find->m_next) {
     768        if (!strcmp(mod, find->m_name)) {
     769            // found ->dequeue it
     770
     771            if (find->m_prev)
     772                find->m_prev->m_next = find->m_next;
    784773            else
    785                 *head = find-> m_next;
    786 
    787             if ( find-> m_next )
    788                 find-> m_next-> m_prev = find-> m_prev;
     774                *head = find->m_next;
     775
     776            if (find->m_next)
     777                find->m_next->m_prev = find->m_prev;
    789778            else
    790                 *tail = find-> m_prev;
     779                *tail = find->m_prev;
    791780
    792781            break; // there can be only one duplicate
     
    794783    }
    795784
    796     if ( !find ) { // did not find a duplicate
    797         find = (struct mod_list_t *) xmalloc ( sizeof(struct mod_list_t));
    798         find-> m_name = mod;
    799         find-> m_path = path;
    800         find-> m_options = opt;
     785    if (!find) { // did not find a duplicate
     786        find = xmalloc(sizeof(struct mod_list_t));
     787        find->m_name = mod;
     788        find->m_path = path;
     789        find->m_options = opt;
    801790    }
    802791
    803792    // enqueue at tail
    804     if ( *tail )
    805         (*tail)-> m_next = find;
    806     find-> m_prev  = *tail;
    807     find-> m_next  = 0;
    808 
    809     if ( !*head )
     793    if (*tail)
     794        (*tail)->m_next = find;
     795    find->m_prev = *tail;
     796    find->m_next = 0;
     797
     798    if (!*head)
    810799        *head = find;
    811800    *tail = find;
    812801
    813     if ( dt ) {
     802    if (dt) {
    814803        int i;
    815804
    816805        /* Add all dependable module for that new module */
    817         for ( i = 0; i < dt-> m_depcnt; i++ )
    818             check_dep ( dt-> m_deparr [i], head, tail );
    819     }
    820 }
    821 
    822 static int mod_insert ( char *mod, int argc, char **argv )
    823 {
    824     struct mod_list_t *tail = 0;
    825     struct mod_list_t *head = 0;
     806        for (i = 0; i < dt->m_depcnt; i++)
     807            check_dep(dt->m_deparr[i], head, tail);
     808    }
     809}
     810
     811static int mod_insert(char *mod, int argc, char **argv)
     812{
     813    struct mod_list_t *tail = NULL;
     814    struct mod_list_t *head = NULL;
    826815    int rc;
    827816
    828817    // get dep list for module mod
    829     check_dep ( mod, &head, &tail );
    830 
    831     if ( head && tail ) {
    832         if( argc ) {
     818    check_dep(mod, &head, &tail);
     819
     820    rc = 1;
     821    if (head && tail) {
     822        if (argc) {
    833823            int i;
    834824            // append module args
    835             for ( i = 0; i < argc; i++ )
    836                 head->m_options = append_option( head->m_options, argv[i] );
     825            for (i = 0; i < argc; i++)
     826                head->m_options = append_option(head->m_options, argv[i]);
    837827        }
    838828
    839829        // process tail ---> head
    840         if ((rc = mod_process ( tail, 1 )) != 0) {
     830        rc = mod_process(tail, 1);
     831        if (rc) {
    841832            /*
    842833             * In case of using udev, multiple instances of modprobe can be
     
    845836             * fail if the module was loaded, and not by us.
    846837             */
    847             if (already_loaded (mod) )
     838            if (already_loaded(mod))
    848839                rc = 0;
    849840        }
    850841    }
    851     else
    852         rc = 1;
    853 
    854842    return rc;
    855843}
    856844
    857 static int mod_remove ( char *mod )
     845static int mod_remove(char *mod)
    858846{
    859847    int rc;
    860     static struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL };
    861 
    862     struct mod_list_t *head = 0;
    863     struct mod_list_t *tail = 0;
    864 
    865     if ( mod )
    866         check_dep ( mod, &head, &tail );
     848    static const struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL };
     849
     850    struct mod_list_t *head = NULL;
     851    struct mod_list_t *tail = NULL;
     852
     853    if (mod)
     854        check_dep(mod, &head, &tail);
    867855    else  // autoclean
    868         head = tail = &rm_a_dummy;
    869 
    870     if ( head && tail )
    871         rc = mod_process ( head, 0 );  // process head ---> tail
    872     else
    873         rc = 1;
     856        head = tail = (struct mod_list_t*) &rm_a_dummy;
     857
     858    rc = 1;
     859    if (head && tail)
     860        rc = mod_process(head, 0);  // process head ---> tail
    874861    return rc;
    875 
    876 }
    877 
     862}
     863
     864int modprobe_main(int argc, char** argv);
    878865int modprobe_main(int argc, char** argv)
    879866{
     
    881868    char *unused;
    882869
    883     bb_opt_complementally = "?V-:q-v:v-q";
    884     main_opts = bb_getopt_ulflags(argc, argv, "acdklnqrst:vVC:",
     870    opt_complementary = "?V-:q-v:v-q";
     871    main_opts = getopt32(argv, "acdklnqrst:vVC:",
    885872                            &unused, &unused);
    886     if((main_opts & (DUMP_CONF_EXIT | LIST_ALL)))
    887                 return EXIT_SUCCESS;
    888     if((main_opts & (RESTRICT_DIR | CONFIG_FILE)))
    889                 bb_error_msg_and_die("-t and -C not supported");
    890 
    891     depend = build_dep ( );
    892 
    893     if ( !depend )
    894         bb_error_msg_and_die ( "could not parse modules.dep" );
     873    if (main_opts & (DUMP_CONF_EXIT | LIST_ALL))
     874        return EXIT_SUCCESS;
     875    if (main_opts & (RESTRICT_DIR | CONFIG_FILE))
     876        bb_error_msg_and_die("-t and -C not supported");
     877
     878    depend = build_dep();
     879
     880    if (!depend)
     881        bb_error_msg_and_die("cannot parse modules.dep");
    895882
    896883    if (remove_opt) {
    897884        do {
    898             if (mod_remove ( optind < argc ?
    899                         argv [optind] : NULL )) {
    900                 bb_error_msg ("failed to remove module %s",
    901                         argv [optind] );
     885            if (mod_remove(optind < argc ?
     886                        argv[optind] : NULL)) {
     887                bb_error_msg("failed to remove module %s",
     888                        argv[optind]);
    902889                rc = EXIT_FAILURE;
    903890            }
    904         } while ( ++optind < argc );
     891        } while (++optind < argc);
    905892    } else {
    906893        if (optind >= argc)
    907             bb_error_msg_and_die ( "No module or pattern provided" );
    908 
    909         if ( mod_insert ( argv [optind], argc - optind - 1, argv + optind + 1 ))
    910             bb_error_msg_and_die ( "failed to load module %s", argv [optind] );
     894            bb_error_msg_and_die("no module or pattern provided");
     895
     896        if (mod_insert(argv[optind], argc - optind - 1, argv + optind + 1))
     897            bb_error_msg_and_die("failed to load module %s", argv[optind]);
    911898    }
    912899
Note: See TracChangeset for help on using the changeset viewer.