X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnu%2Fmodechange.c;h=4d003c0a41d0ce166d40a60f3c0a27ef6c22a029;hb=daa269958ad8d50ef8154ccb65e58acaf7a6dd99;hp=97a8d1a5b22d8b5004829fb8b40f81aa00b1a060;hpb=1a44d77d50f4fb37c0410eed04b82303624ea2ec;p=debian%2Ftar diff --git a/gnu/modechange.c b/gnu/modechange.c index 97a8d1a5..4d003c0a 100644 --- a/gnu/modechange.c +++ b/gnu/modechange.c @@ -2,7 +2,7 @@ /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ /* modechange.c -- file mode manipulation - Copyright (C) 1989-1990, 1997-1999, 2001, 2003-2006, 2009-2011 Free Software + Copyright (C) 1989-1990, 1997-1999, 2001, 2003-2006, 2009-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -20,7 +20,7 @@ /* Written by David MacKenzie */ -/* The ASCII mode string is compiled into an array of `struct +/* The ASCII mode string is compiled into an array of 'struct modechange', which can then be applied to each file to be changed. We do this instead of re-parsing the ASCII string for each file because the compiled form requires less computation to use; when @@ -92,7 +92,7 @@ enum /* Instead of the typical case, copy some existing permissions for u, g, or o onto the other two. Which of u, g, or o is copied - is determined by which bits are set in the `value' field. */ + is determined by which bits are set in the 'value' field. */ MODE_COPY_EXISTING }; @@ -106,8 +106,8 @@ struct mode_change mode_t mentioned; /* Bits explicitly mentioned. */ }; -/* Return a mode_change array with the specified `=ddd'-style - mode change operation, where NEW_MODE is `ddd' and MENTIONED +/* Return a mode_change array with the specified "=ddd"-style + mode change operation, where NEW_MODE is "ddd" and MENTIONED contains the bits explicitly mentioned in the mode are MENTIONED. */ static struct mode_change * @@ -129,7 +129,7 @@ make_node_op_equals (mode_t new_mode, mode_t mentioned) the form: [ugoa...][[+-=][rwxXstugo...]...][,...] - Return NULL if `mode_string' does not contain a valid + Return NULL if 'mode_string' does not contain a valid representation of file mode change operations. */ struct mode_change * @@ -138,6 +138,7 @@ mode_compile (char const *mode_string) /* The array of mode-change directives to be returned. */ struct mode_change *mc; size_t used = 0; + char const *p; if ('0' <= *mode_string && *mode_string < '8') { @@ -145,40 +146,43 @@ mode_compile (char const *mode_string) mode_t mode; mode_t mentioned; + p = mode_string; do { - octal_mode = 8 * octal_mode + *mode_string++ - '0'; + octal_mode = 8 * octal_mode + *p++ - '0'; if (ALLM < octal_mode) return NULL; } - while ('0' <= *mode_string && *mode_string < '8'); + while ('0' <= *p && *p < '8'); - if (*mode_string) + if (*p) return NULL; mode = octal_to_mode (octal_mode); - mentioned = (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO; + mentioned = (p - mode_string < 5 + ? (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO + : CHMOD_MODE_BITS); return make_node_op_equals (mode, mentioned); } /* Allocate enough space to hold the result. */ { size_t needed = 1; - char const *p; for (p = mode_string; *p; p++) needed += (*p == '=' || *p == '+' || *p == '-'); mc = xnmalloc (needed, sizeof *mc); } - /* One loop iteration for each `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'. */ - for (;; mode_string++) + /* One loop iteration for each + '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'. */ + for (p = mode_string; ; p++) { /* Which bits in the mode are operated on. */ mode_t affected = 0; - /* Turn on all the bits in `affected' for each group given. */ - for (;; mode_string++) - switch (*mode_string) + /* Turn on all the bits in 'affected' for each group given. */ + for (;; p++) + switch (*p) { default: goto invalid; @@ -201,35 +205,60 @@ mode_compile (char const *mode_string) do { - char op = *mode_string++; + char op = *p++; mode_t value; + mode_t mentioned = 0; char flag = MODE_COPY_EXISTING; struct mode_change *change; - switch (*mode_string++) + switch (*p) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + unsigned int octal_mode = 0; + + do + { + octal_mode = 8 * octal_mode + *p++ - '0'; + if (ALLM < octal_mode) + return NULL; + } + while ('0' <= *p && *p < '8'); + + if (affected || (*p && *p != ',')) + return NULL; + affected = mentioned = CHMOD_MODE_BITS; + value = octal_to_mode (octal_mode); + flag = MODE_ORDINARY_CHANGE; + break; + } + case 'u': - /* Set the affected bits to the value of the `u' bits + /* Set the affected bits to the value of the "u" bits on the same file. */ value = S_IRWXU; + p++; break; case 'g': - /* Set the affected bits to the value of the `g' bits + /* Set the affected bits to the value of the "g" bits on the same file. */ value = S_IRWXG; + p++; break; case 'o': - /* Set the affected bits to the value of the `o' bits + /* Set the affected bits to the value of the "o" bits on the same file. */ value = S_IRWXO; + p++; break; default: value = 0; flag = MODE_ORDINARY_CHANGE; - for (mode_string--;; mode_string++) - switch (*mode_string) + for (;; p++) + switch (*p) { case 'r': value |= S_IRUSR | S_IRGRP | S_IROTH; @@ -244,11 +273,11 @@ mode_compile (char const *mode_string) flag = MODE_X_IF_ANY_X; break; case 's': - /* Set the setuid/gid bits if `u' or `g' is selected. */ + /* Set the setuid/gid bits if 'u' or 'g' is selected. */ value |= S_ISUID | S_ISGID; break; case 't': - /* Set the "save text image" bit if `o' is selected. */ + /* Set the "save text image" bit if 'o' is selected. */ value |= S_ISVTX; break; default: @@ -262,16 +291,16 @@ mode_compile (char const *mode_string) change->flag = flag; change->affected = affected; change->value = value; - change->mentioned = (affected ? affected & value : value); + change->mentioned = + (mentioned ? mentioned : affected ? affected & value : value); } - while (*mode_string == '=' || *mode_string == '+' - || *mode_string == '-'); + while (*p == '=' || *p == '+' || *p == '-'); - if (*mode_string != ',') + if (*p != ',') break; } - if (*mode_string == 0) + if (*p == 0) { mc[used].flag = MODE_DONE; return mc; @@ -331,7 +360,7 @@ mode_adjust (mode_t oldmode, bool dir, mode_t umask_value, break; case MODE_COPY_EXISTING: - /* Isolate in `value' the bits in `newmode' to copy. */ + /* Isolate in 'value' the bits in 'newmode' to copy. */ value &= newmode; /* Copy the isolated bits to the other two parts. */