X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/cf9b4794fdcd71feef63585e2497642fc658c810..15b03ab1a84ccf4d68963725b20f955d56e5731f:/chmod.c diff --git a/chmod.c b/chmod.c index 3f9c8b43..53aa0595 100644 --- a/chmod.c +++ b/chmod.c @@ -21,10 +21,10 @@ struct chmod_mode_struct { #define STATE_2ND_HALF 2 /* Parse a chmod-style argument, and break it down into one or more AND/OR - * pairs in a linked list. We use a state machine to walk through the - * options. */ + * pairs in a linked list. We return a pointer to new items on succcess + * (appending the items to the specified list), or NULL on error. */ struct chmod_mode_struct *parse_chmod(const char *modestr, - struct chmod_mode_struct *append_to) + struct chmod_mode_struct **root_mode_ptr) { int state = STATE_1ST_HALF; int where = 0, what = 0, op = 0, topbits = 0, topoct = 0, flags = 0; @@ -157,11 +157,12 @@ struct chmod_mode_struct *parse_chmod(const char *modestr, return NULL; } - if (append_to) { - for (prev_mode = append_to; prev_mode->next; ) - prev_mode = prev_mode->next; - prev_mode->next = first_mode; - return append_to; + if (!(curr_mode = *root_mode_ptr)) + *root_mode_ptr = first_mode; + else { + while (curr_mode->next) + curr_mode = curr_mode->next; + curr_mode->next = first_mode; } return first_mode;