Changed the code to use the new flag var in the struct idlist instead
authorWayne Davison <wayned@samba.org>
Sun, 20 May 2007 08:27:27 +0000 (08:27 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 20 May 2007 08:27:27 +0000 (08:27 +0000)
of negative id values.  Fixed failing hunks too.

usermap.diff

index bb294dc..0941ce5 100644 (file)
@@ -18,22 +18,22 @@ To use this patch, run these commands for a successful build:
  extern struct stats stats;
  
  extern char curr_dir[MAXPATHLEN];
-@@ -741,7 +743,7 @@ static struct file_struct *recv_file_ent
+@@ -742,7 +744,7 @@ static struct file_struct *recv_file_ent
                        uid = (uid_t)read_varint(f);
-                       if (flags & XMIT_USER_NAME_FOLLOWS)
+                       if (xflags & XMIT_USER_NAME_FOLLOWS)
                                uid = recv_user_name(f, uid);
 -                      else if (inc_recurse && am_root && !numeric_ids)
 +                      else if (inc_recurse && am_root && (!numeric_ids || usermap))
                                uid = match_uid(uid);
                }
        }
-@@ -752,7 +754,7 @@ static struct file_struct *recv_file_ent
+@@ -753,7 +755,7 @@ static struct file_struct *recv_file_ent
                        gid = (gid_t)read_varint(f);
-                       if (flags & XMIT_GROUP_NAME_FOLLOWS)
-                               gid = recv_group_name(f, gid);
+                       if (xflags & XMIT_GROUP_NAME_FOLLOWS)
+                               gid = recv_group_name(f, gid, &new_flags);
 -                      else if (inc_recurse && (!am_root || !numeric_ids))
 +                      else if (inc_recurse && (!am_root || !numeric_ids || groupmap))
-                               gid = match_gid(gid);
+                               gid = match_gid(gid, &new_flags);
                }
        }
 @@ -1882,8 +1884,13 @@ struct file_list *recv_file_list(int f)
@@ -159,17 +159,27 @@ To use this patch, run these commands for a successful build:
  then rsync will exit. The default is 0, which means no timeout.
 --- old/uidlist.c
 +++ new/uidlist.c
-@@ -38,6 +38,8 @@ extern int preserve_uid;
+@@ -32,6 +32,8 @@ extern int preserve_uid;
  extern int preserve_gid;
  extern int preserve_acls;
  extern int numeric_ids;
 +extern char *usermap;
 +extern char *groupmap;
  
+ #ifdef HAVE_GETGROUPS
+ # ifndef GETGROUPS_T
+@@ -41,6 +43,9 @@ extern int numeric_ids;
+ #define GID_NONE ((gid_t)-1)
++#define NFLAGS_WILD_NAME_MATCH (1<<0)
++#define NFLAGS_NAME_MATCH (1<<1)
++
  struct idlist {
        struct idlist *next;
-@@ -45,8 +47,8 @@ struct idlist {
        char *name;
+@@ -48,8 +53,8 @@ struct idlist {
+       uint16 flags;
  };
  
 -static struct idlist *uidlist;
@@ -177,9 +187,9 @@ To use this patch, run these commands for a successful build:
 +static struct idlist *uidlist, *uidmap;
 +static struct idlist *gidlist, *gidmap;
  
- static struct idlist *add_to_list(struct idlist **root, int id, char *name,
-                                 int id2)
-@@ -80,22 +82,6 @@ static char *gid_to_name(gid_t gid)
+ static struct idlist *add_to_list(struct idlist **root, id_t id, char *name,
+                                 id_t id2, uint16 flags)
+@@ -84,22 +89,6 @@ static char *gid_to_name(gid_t gid)
        return NULL;
  }
  
@@ -202,40 +212,36 @@ To use this patch, run these commands for a successful build:
  static int is_in_group(gid_t gid)
  {
  #ifdef HAVE_GETGROUPS
-@@ -155,35 +141,52 @@ static int is_in_group(gid_t gid)
+@@ -159,34 +148,49 @@ static int is_in_group(gid_t gid)
  #endif
  }
  
 -/* Add a uid to the list of uids.  Only called on receiving side. */
--static uid_t recv_add_uid(uid_t id, char *name)
+-static struct idlist *recv_add_uid(uid_t id, char *name)
 +/* Add a uid/gid to its list of ids.  Only called on receiving side. */
-+static int recv_add_id(struct idlist **idmap_ptr, int id, char *name)
++static struct idlist *recv_add_id(struct idlist **idmap_ptr, id_t id, char *name)
  {
 -      uid_t id2 = name ? map_uid(id, name) : id;
        struct idlist *node;
-+      int id2;
++      id_t id2;
  
--      node = add_to_list(&uidlist, (int)id, name, (int)id2);
+-      node = add_to_list(&uidlist, id, name, id2, 0);
 +      if (!name)
 +              name = "";
  
 -      if (verbose > 3) {
--              rprintf(FINFO, "uid %d(%s) maps to %d\n",
--                      (int)id, name ? name : "", (int)id2);
+-              rprintf(FINFO, "uid %u(%s) maps to %u\n",
+-                      (unsigned)id, name ? name : "", (unsigned)id2);
 +      for (node = *idmap_ptr; node; node = node->next) {
-+              switch (node->id) {
-+              case -2:
++              if (node->flags & NFLAGS_WILD_NAME_MATCH) {
 +                      if (!wildmatch(node->name, name))
 +                              continue;
-+                      break;
-+              case -1:
++              } else if (node->flags & NFLAGS_NAME_MATCH) {
 +                      if (strcmp(node->name, name) != 0)
 +                              continue;
-+                      break;
-+              default:
++              } else {
 +                      if (node->id != id)
 +                              continue;
-+                      break;
 +              }
 +              break;
        }
@@ -244,38 +250,39 @@ To use this patch, run these commands for a successful build:
 +      else if (*name && id) {
 +              if (idmap_ptr == &uidmap) {
 +                      uid_t uid;
-+                      id2 = name_to_uid(name, &uid) ? (int)uid : id;
++                      id2 = name_to_uid(name, &uid) ? uid : id;
 +              } else {
 +                      gid_t gid;
-+                      id2 = name_to_gid(name, &gid) ? (int)gid : id;
++                      id2 = name_to_gid(name, &gid) ? gid : id;
 +              }
 +      } else
 +              id2 = id;
  
--      return id2;
+-      return node;
 -}
 -
 -/* Add a gid to the list of gids.  Only called on receiving side. */
--static gid_t recv_add_gid(gid_t id, char *name)
+-static struct idlist *recv_add_gid(gid_t id, char *name)
 -{
 -      gid_t id2 = name ? map_gid(id, name) : id;
 -      struct idlist *node;
 -
--      if (!am_root && !is_in_group(id2))
-+      if (idmap_ptr == &gidmap && !am_root && !is_in_group(id2))
-               id2 = GID_NONE;
--      node = add_to_list(&gidlist, (int)id, name, (int)id2);
-+      node = add_to_list(idmap_ptr, id, *name ? name : NULL, id2);
+-      node = add_to_list(&gidlist, id, name, id2,
+-              !am_root && !is_in_group(id2) ? FLAG_SKIP_GROUP : 0);
++      node = add_to_list(idmap_ptr, id, *name ? name : NULL, id2,
++              !am_root && idmap_ptr == &gidmap
++              && !is_in_group(id2) ? FLAG_SKIP_GROUP : 0);
  
        if (verbose > 3) {
--              rprintf(FINFO, "gid %d(%s) maps to %d\n",
--                      (int)id, name ? name : "", (int)id2);
-+              rprintf(FINFO, "%sid %d(%s) maps to %d\n",
-+                      idmap_ptr == &uidmap ? "u" : "g", id, name, id2);
+-              rprintf(FINFO, "gid %u(%s) maps to %u\n",
+-                      (unsigned)id, name ? name : "", (unsigned)id2);
++              rprintf(FINFO, "%sid %u(%s) maps to %u\n",
++                      idmap_ptr == &uidmap ? "u" : "g",
++                      (unsigned)id, name, (unsigned)id2);
        }
  
-       return id2;
-@@ -192,12 +195,9 @@ static gid_t recv_add_gid(gid_t id, char
+       return node;
+@@ -195,12 +199,9 @@ static struct idlist *recv_add_gid(gid_t
  /* this function is a definate candidate for a faster algorithm */
  uid_t match_uid(uid_t uid)
  {
@@ -289,59 +296,68 @@ To use this patch, run these commands for a successful build:
        if (uid == last_in)
                return last_out;
  
-@@ -208,7 +208,7 @@ uid_t match_uid(uid_t uid)
-                       return last_out = (uid_t)list->id2;
+@@ -208,10 +209,13 @@ uid_t match_uid(uid_t uid)
+       for (list = uidlist; list; list = list->next) {
+               if (list->id == uid)
+-                      return last_out = list->id2;
++                      break;
        }
  
 -      return last_out = uid;
-+      return last_out = (uid_t)recv_add_id(&uidmap, (int)uid, NULL);
++      if (!list)
++              list = recv_add_id(&uidmap, uid, NULL);
++
++      return last_out = list->id2;
  }
  
- gid_t match_gid(gid_t gid)
-@@ -229,7 +229,7 @@ gid_t match_gid(gid_t gid)
-                       return last_out = (gid_t)list->id2;
+ gid_t match_gid(gid_t gid, uint16 *flags_ptr)
+@@ -230,7 +234,7 @@ gid_t match_gid(gid_t gid, uint16 *flags
        }
  
--      return last_out = recv_add_gid(gid, NULL);
-+      return last_out = (gid_t)recv_add_id(&gidmap, (int)gid, NULL);
- }
+       if (!list)
+-              list = recv_add_gid(gid, NULL);
++              list = recv_add_id(&gidmap, gid, NULL);
  
- /* Add a uid to the list of uids.  Only called on sending side. */
-@@ -311,7 +311,7 @@ uid_t recv_user_name(int f, uid_t uid)
+       if (flags_ptr && list->flags & FLAG_SKIP_GROUP)
+               *flags_ptr |= FLAG_SKIP_GROUP;
+@@ -317,7 +321,7 @@ uid_t recv_user_name(int f, uid_t uid)
        if (!name)
                out_of_memory("recv_user_name");
        read_sbuf(f, name, len);
--      return recv_add_uid(uid, name); /* node keeps name's memory */
-+      return (uid_t)recv_add_id(&uidmap, (int)uid, name); /* node keeps name's memory */
+-      node = recv_add_uid(uid, name); /* node keeps name's memory */
++      node = recv_add_id(&uidmap, uid, name); /* node keeps name's memory */
+       return node->id2;
  }
  
- gid_t recv_group_name(int f, gid_t gid)
-@@ -321,7 +321,7 @@ gid_t recv_group_name(int f, gid_t gid)
+@@ -329,7 +333,7 @@ gid_t recv_group_name(int f, gid_t gid, 
        if (!name)
                out_of_memory("recv_group_name");
        read_sbuf(f, name, len);
--      return recv_add_gid(gid, name); /* node keeps name's memory */
-+      return (gid_t)recv_add_id(&gidmap, (int)gid, name); /* node keeps name's memory */
- }
- /* recv a complete uid/gid mapping from the peer and map the uid/gid
-@@ -344,15 +344,88 @@ void recv_uid_list(int f, struct file_li
+-      node = recv_add_gid(gid, name); /* node keeps name's memory */
++      node = recv_add_id(&gidmap, gid, name); /* node keeps name's memory */
+       if (flags_ptr && node->flags & FLAG_SKIP_GROUP)
+               *flags_ptr |= FLAG_SKIP_GROUP;
+       return node->id2;
+@@ -356,17 +360,96 @@ void recv_id_list(int f, struct file_lis
  
        /* Now convert all the uids/gids from sender values to our values. */
  #ifdef SUPPORT_ACLS
 -      if (preserve_acls && !numeric_ids)
-+      if (preserve_acls && (!numeric_ids || usermap))
++      if (preserve_acls && (!numeric_ids || usermap || groupmap))
                match_acl_ids();
  #endif
 -      if (am_root && preserve_uid && !numeric_ids) {
 +      if (am_root && preserve_uid && (!numeric_ids || usermap)) {
                for (i = 0; i < flist->count; i++)
-                       F_OWNER(flist->files[i]) = match_uid(F_UID(flist->files[i]));
+                       F_OWNER(flist->files[i]) = match_uid(F_OWNER(flist->files[i]));
        }
 -      if (preserve_gid && (!am_root || !numeric_ids)) {
 +      if (preserve_gid && (!am_root || !numeric_ids || groupmap)) {
-               for (i = 0; i < flist->count; i++)
-                       F_GROUP(flist->files[i]) = match_gid(F_GID(flist->files[i]));
+               for (i = 0; i < flist->count; i++) {
+                       F_GROUP(flist->files[i]) = match_gid(F_GROUP(flist->files[i]),
+                                                            &flist->files[i]->flags);
+               }
        }
  }
 +
@@ -350,7 +366,8 @@ To use this patch, run these commands for a successful build:
 +      struct idlist **idmap_ptr = usernames ? &uidmap : &gidmap;
 +      struct idlist **idlist_ptr = usernames ? &uidlist : &gidlist;
 +      char *colon, *end, *cp = map + strlen(map);
-+      int id1, id2;
++      id_t id1, id2;
++      uint16 flags;
 +
 +      while (1) {
 +              end = cp;
@@ -369,11 +386,15 @@ To use this patch, run these commands for a successful build:
 +                                      usernames ? "user" : "group", cp);
 +                              exit_cleanup(RERR_SYNTAX);
 +                      }
++                      flags = 0;
 +                      id1 = atoi(cp);
-+              } else if (strpbrk(cp, "*[?"))
-+                      id1 = -2;
-+              else
-+                      id1 = -1;
++              } else if (strpbrk(cp, "*[?")) {
++                      flags = NFLAGS_WILD_NAME_MATCH;
++                      id1 = 0;
++              } else {
++                      flags = NFLAGS_NAME_MATCH;
++                      id1 = 0;
++              }
 +
 +              if (isDigit(colon+1)) {
 +                      if (strspn(colon+1, "0123456789") != (size_t)(end - colon - 1)) {
@@ -392,18 +413,18 @@ To use this patch, run these commands for a successful build:
 +                                              colon+1);
 +                                      exit_cleanup(RERR_SYNTAX);
 +                              }
-+                              id2 = (int)uid;
++                              id2 = uid;
 +                      } else {
 +                              gid_t gid;
 +                              if (!name_to_gid(colon+1, &gid))
 +                                      goto bad_name;
-+                              id2 = (int)gid;
++                              id2 = gid;
 +                      }
 +              }
 +
-+              add_to_list(idmap_ptr, id1, id1 < 0 ? cp : NULL, id2);
-+              if (numeric_ids && id2 >= 0)
-+                      add_to_list(idlist_ptr, id1, NULL, id2);
++              add_to_list(idmap_ptr, id1, flags ? cp : NULL, id2, flags);
++              if (numeric_ids && !flags)
++                      add_to_list(idlist_ptr, id1, NULL, id2, flags);
 +
 +              if (cp == map)
 +                      break;
@@ -411,6 +432,7 @@ To use this patch, run these commands for a successful build:
 +              *--cp = '\0'; /* replace comma */
 +      }
 +
++      /* The 0 user/group doesn't get its name sent, or add it explicitly. */
 +      if (numeric_ids)
 +              cp = NULL;
 +      else