+/* Add a uid/gid to its list of ids. Only called on receiving side. */
+static struct idlist *recv_add_id(struct idlist **idlist_ptr, struct idlist *idmap,
+ id_t id, const char *name)
+{
+ struct idlist *node;
+ int flag;
+ id_t id2;
+
+ if (!name)
+ name = "";
+
+ for (node = idmap; node; node = node->next) {
+ if (node->flags & NFLAGS_WILD_NAME_MATCH) {
+ if (!wildmatch(node->name, name))
+ continue;
+ } else if (node->flags & NFLAGS_NAME_MATCH) {
+ if (strcmp(node->name, name) != 0)
+ continue;
+ } else if (node->name) {
+ if (id < node->id || id > (unsigned long)node->name)
+ continue;
+ } else {
+ if (node->id != id)
+ continue;
+ }
+ break;
+ }
+ if (node)
+ id2 = node->id2;
+ else if (*name && id) {
+ if (idlist_ptr == &uidlist) {
+ uid_t uid;
+ id2 = name_to_uid(name, &uid) ? uid : id;
+ } else {
+ gid_t gid;
+ id2 = name_to_gid(name, &gid) ? gid : id;
+ }
+ } else
+ id2 = id;
+
+ flag = idlist_ptr == &gidlist && !am_root && !is_in_group(id2) ? FLAG_SKIP_GROUP : 0;
+ node = add_to_list(idlist_ptr, id, *name ? name : NULL, id2, flag);
+
+ if (DEBUG_GTE(OWN, 2)) {
+ rprintf(FINFO, "%sid %u(%s) maps to %u\n",
+ idlist_ptr == &uidlist ? "u" : "g",
+ (unsigned)id, name, (unsigned)id2);
+ }
+
+ return node;
+}
+