Diff for /embedaddon/rsync/exclude.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/10/14 07:51:14 version 1.1.1.3, 2016/11/01 09:54:32
Line 4 Line 4
  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>   * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 1996 Paul Mackerras   * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool   * Copyright (C) 2002 Martin Pool
 * Copyright (C) 2003-2013 Wayne Davison * Copyright (C) 2003-2015 Wayne Davison
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
Line 100  static int mergelist_size = 0; Line 100  static int mergelist_size = 0;
   
 static void teardown_mergelist(filter_rule *ex)  static void teardown_mergelist(filter_rule *ex)
 {  {
           int j;
   
           if (!ex->u.mergelist)
                   return;
   
         if (DEBUG_GTE(FILTER, 2)) {          if (DEBUG_GTE(FILTER, 2)) {
                 rprintf(FINFO, "[%s] deactivating mergelist #%d%s\n",                  rprintf(FINFO, "[%s] deactivating mergelist #%d%s\n",
                         who_am_i(), mergelist_cnt - 1,                          who_am_i(), mergelist_cnt - 1,
                         ex->u.mergelist->debug_type);                          ex->u.mergelist->debug_type);
         }          }
   
         /* We should deactivate mergelists in LIFO order. */  
         assert(mergelist_cnt > 0);  
         assert(ex == mergelist_parents[mergelist_cnt - 1]);  
   
         /* The parent_dirscan filters should have been freed. */  
         assert(ex->u.mergelist->parent_dirscan_head == NULL);  
   
         free(ex->u.mergelist->debug_type);          free(ex->u.mergelist->debug_type);
         free(ex->u.mergelist);          free(ex->u.mergelist);
        mergelist_cnt--;
         for (j = 0; j < mergelist_cnt; j++) {
                 if (mergelist_parents[j] == ex) {
                         mergelist_parents[j] = NULL;
                         break;
                 }
         }
         while (mergelist_cnt && mergelist_parents[mergelist_cnt-1] == NULL)
                 mergelist_cnt--;
 }  }
   
 static void free_filter(filter_rule *ex)  static void free_filter(filter_rule *ex)
 {  {
           if (ex->rflags & FILTRULE_PERDIR_MERGE)
                   teardown_mergelist(ex);
         free(ex->pattern);          free(ex->pattern);
         free(ex);          free(ex);
 }  }
   
static void free_filters(filter_rule *head)static void free_filters(filter_rule *ent)
 {  {
        filter_rule *rev_head = NULL;        while (ent) {
                filter_rule *next = ent->next;
        /* Reverse the list so we deactivate mergelists in the proper LIFO                free_filter(ent);
         * order. */                ent = next;
        while (head) { 
                filter_rule *next = head->next; 
                head->next = rev_head; 
                rev_head = head; 
                head = next; 
         }          }
   
         while (rev_head) {  
                 filter_rule *prev = rev_head->next;  
                 /* Tear down mergelists here, not in free_filter, so that we  
                  * affect only real filter lists and not temporarily allocated  
                  * filters. */  
                 if (rev_head->rflags & FILTRULE_PERDIR_MERGE)  
                         teardown_mergelist(rev_head);  
                 free_filter(rev_head);  
                 rev_head = prev;  
         }  
 }  }
   
 /* Build a filter structure given a filter pattern.  The value in "pat"  /* Build a filter structure given a filter pattern.  The value in "pat"
Line 252  static void add_rule(filter_rule_list *listp, const ch Line 244  static void add_rule(filter_rule_list *listp, const ch
                  * add it again. */                   * add it again. */
                 for (i = 0; i < mergelist_cnt; i++) {                  for (i = 0; i < mergelist_cnt; i++) {
                         filter_rule *ex = mergelist_parents[i];                          filter_rule *ex = mergelist_parents[i];
                        const char *s = strrchr(ex->pattern, '/');                        const char *s;
                         if (!ex)
                                 continue;
                         s = strrchr(ex->pattern, '/');
                         if (s)                          if (s)
                                 s++;                                  s++;
                         else                          else
Line 264  static void add_rule(filter_rule_list *listp, const ch Line 259  static void add_rule(filter_rule_list *listp, const ch
                         }                          }
                 }                  }
   
                if (!(lp = new_array(filter_rule_list, 1)))                if (!(lp = new_array0(filter_rule_list, 1)))
                         out_of_memory("add_rule");                          out_of_memory("add_rule");
                 lp->head = lp->tail = lp->parent_dirscan_head = NULL;  
                 if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)                  if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
                         out_of_memory("add_rule");                          out_of_memory("add_rule");
                 rule->u.mergelist = lp;                  rule->u.mergelist = lp;
Line 297  static void add_rule(filter_rule_list *listp, const ch Line 291  static void add_rule(filter_rule_list *listp, const ch
         }          }
 }  }
   
static void clear_filter_list(filter_rule_list *listp)/* This frees any non-inherited items, leaving just inherited items on the list. */
 static void pop_filter_list(filter_rule_list *listp)
 {  {
        if (listp->tail) {        filter_rule *inherited;
                /* Truncate any inherited items from the local list. */ 
                listp->tail->next = NULL; 
                /* Now free everything that is left. */ 
                free_filters(listp->head); 
        } 
   
        listp->head = listp->tail = NULL;        if (!listp->tail)
                 return;
 
         inherited = listp->tail->next;
 
         /* Truncate any inherited items from the local list. */
         listp->tail->next = NULL;
         /* Now free everything that is left. */
         free_filters(listp->head);
 
         listp->head = inherited;
         listp->tail = NULL;
 }  }
   
 /* This returns an expanded (absolute) filename for the merge-file name if  /* This returns an expanded (absolute) filename for the merge-file name if
Line 356  static char *parse_merge_name(const char *merge_file,  Line 357  static char *parse_merge_name(const char *merge_file, 
                 fn_len = clean_fname(fn, CFN_COLLAPSE_DOT_DOT_DIRS);                  fn_len = clean_fname(fn, CFN_COLLAPSE_DOT_DOT_DIRS);
         }          }
   
        /* If the name isn't in buf yet, it's wasn't absolute. */        /* If the name isn't in buf yet, it wasn't absolute. */
         if (fn != buf) {          if (fn != buf) {
                 int d_len = dirbuf_len - prefix_skip;                  int d_len = dirbuf_len - prefix_skip;
                 if (d_len + fn_len >= MAXPATHLEN) {                  if (d_len + fn_len >= MAXPATHLEN) {
Line 457  static BOOL setup_merge_file(int mergelist_num, filter Line 458  static BOOL setup_merge_file(int mergelist_num, filter
                 strlcpy(y, save, MAXPATHLEN);                  strlcpy(y, save, MAXPATHLEN);
                 while ((*x++ = *y++) != '/') {}                  while ((*x++ = *y++) != '/') {}
         }          }
         /* Save current head for freeing when the mergelist becomes inactive. */  
         lp->parent_dirscan_head = lp->head;  
         parent_dirscan = False;          parent_dirscan = False;
         if (DEBUG_GTE(FILTER, 2)) {          if (DEBUG_GTE(FILTER, 2)) {
                 rprintf(FINFO, "[%s] completed parent_dirscan for mergelist #%d%s\n",                  rprintf(FINFO, "[%s] completed parent_dirscan for mergelist #%d%s\n",
Line 501  void *push_local_filters(const char *dir, unsigned int Line 500  void *push_local_filters(const char *dir, unsigned int
   
         push->mergelist_cnt = mergelist_cnt;          push->mergelist_cnt = mergelist_cnt;
         for (i = 0; i < mergelist_cnt; i++) {          for (i = 0; i < mergelist_cnt; i++) {
                memcpy(&push->mergelists[i], mergelist_parents[i]->u.mergelist,                filter_rule *ex = mergelist_parents[i];
                       sizeof (filter_rule_list));                if (!ex)
                         continue;
                 memcpy(&push->mergelists[i], ex->u.mergelist, sizeof (filter_rule_list));
         }          }
   
         /* Note: parse_filter_file() might increase mergelist_cnt, so keep          /* Note: parse_filter_file() might increase mergelist_cnt, so keep
          * this loop separate from the above loop. */           * this loop separate from the above loop. */
         for (i = 0; i < mergelist_cnt; i++) {          for (i = 0; i < mergelist_cnt; i++) {
                 filter_rule *ex = mergelist_parents[i];                  filter_rule *ex = mergelist_parents[i];
                filter_rule_list *lp = ex->u.mergelist;                filter_rule_list *lp;
                 if (!ex)
                         continue;
                 lp = ex->u.mergelist;
   
                 if (DEBUG_GTE(FILTER, 2)) {                  if (DEBUG_GTE(FILTER, 2)) {
                         rprintf(FINFO, "[%s] pushing mergelist #%d%s\n",                          rprintf(FINFO, "[%s] pushing mergelist #%d%s\n",
Line 553  void pop_local_filters(void *mem) Line 557  void pop_local_filters(void *mem)
   
         for (i = mergelist_cnt; i-- > 0; ) {          for (i = mergelist_cnt; i-- > 0; ) {
                 filter_rule *ex = mergelist_parents[i];                  filter_rule *ex = mergelist_parents[i];
                filter_rule_list *lp = ex->u.mergelist;                filter_rule_list *lp;
                 if (!ex)
                         continue;
                 lp = ex->u.mergelist;
   
                 if (DEBUG_GTE(FILTER, 2)) {                  if (DEBUG_GTE(FILTER, 2)) {
                         rprintf(FINFO, "[%s] popping mergelist #%d%s\n",                          rprintf(FINFO, "[%s] popping mergelist #%d%s\n",
                                 who_am_i(), i, lp->debug_type);                                  who_am_i(), i, lp->debug_type);
                 }                  }
   
                clear_filter_list(lp);                pop_filter_list(lp);
                if (i >= old_mergelist_cnt && lp->head) {
                if (i >= old_mergelist_cnt) {                        /* This mergelist does not exist in the state to be restored, but it
                        /* This mergelist does not exist in the state to be                         * still has inherited rules.  This can sometimes happen if a per-dir
                         * restored.  Free its parent_dirscan list to clean up                         * merge file calls setup_merge_file() in push_local_filters() and that
                         * any per-dir mergelists defined there so we don't                         * leaves some inherited rules that aren't in the pushed list state. */
                         * crash trying to restore nonexistent state for them 
                         * below.  (Counterpart to setup_merge_file call in 
                         * push_local_filters.  Must be done here, not in 
                         * free_filter, for LIFO order.) */ 
                         if (DEBUG_GTE(FILTER, 2)) {                          if (DEBUG_GTE(FILTER, 2)) {
                                 rprintf(FINFO, "[%s] freeing parent_dirscan filters of mergelist #%d%s\n",                                  rprintf(FINFO, "[%s] freeing parent_dirscan filters of mergelist #%d%s\n",
                                         who_am_i(), i, ex->u.mergelist->debug_type);                                          who_am_i(), i, ex->u.mergelist->debug_type);
                         }                          }
                        free_filters(lp->parent_dirscan_head);                        pop_filter_list(lp);
                        lp->parent_dirscan_head = NULL; 
                 }                  }
         }          }
   
        /* If we cleaned things up properly, the only still-active mergelists        if (!pop)
         * should be those with a state to be restored. */                return; /* No state to restore. */
        assert(mergelist_cnt == old_mergelist_cnt); 
   
        if (!pop) {        for (i = 0; i < old_mergelist_cnt; i++) {
                /* No state to restore. */                filter_rule *ex = mergelist_parents[i];
                return;                if (!ex)
                         continue;
                 memcpy(ex->u.mergelist, &pop->mergelists[i], sizeof (filter_rule_list));
         }          }
   
         for (i = 0; i < mergelist_cnt; i++) {  
                 memcpy(mergelist_parents[i]->u.mergelist, &pop->mergelists[i],  
                        sizeof (filter_rule_list));  
         }  
   
         free(pop);          free(pop);
 }  }
   
Line 872  static filter_rule *parse_rule_tok(const char **rulest Line 870  static filter_rule *parse_rule_tok(const char **rulest
                 switch (ch) {                  switch (ch) {
                 case ':':                  case ':':
                         rule->rflags |= FILTRULE_PERDIR_MERGE                          rule->rflags |= FILTRULE_PERDIR_MERGE
                                       | FILTRULE_FINISH_SETUP;                                      | FILTRULE_FINISH_SETUP;
                         /* FALL THROUGH */                          /* FALL THROUGH */
                 case '.':                  case '.':
                         rule->rflags |= FILTRULE_MERGE_FILE;                          rule->rflags |= FILTRULE_MERGE_FILE;
Line 1093  void parse_filter_str(filter_rule_list *listp, const c Line 1091  void parse_filter_str(filter_rule_list *listp, const c
                                         "[%s] clearing filter list%s\n",                                          "[%s] clearing filter list%s\n",
                                         who_am_i(), listp->debug_type);                                          who_am_i(), listp->debug_type);
                         }                          }
                        clear_filter_list(listp);                        pop_filter_list(listp);
                         listp->head = NULL;
                         goto free_continue;                          goto free_continue;
                 }                  }
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>