Add comment saying this is used by both libarchive and bsdtar.
[dragonfly.git] / usr.bin / tar / patches / write.c.patch
1 $DragonFly: src/usr.bin/tar/patches/Attic/write.c.patch,v 1.1 2004/11/10 18:02:24 joerg Exp $
2
3 --- write.c.orig        2004-11-10 01:04:37.000000000 +0100
4 +++ write.c     2004-11-10 01:12:35.000000000 +0100
5 @@ -91,7 +91,10 @@
6         int     hits;
7         size_t  size;
8         struct {
9 -               id_t id;
10 +               union {
11 +                       uid_t uid;
12 +                       gid_t gid;
13 +               } id;
14                 const char *name;
15         } cache[name_cache_size];
16  };
17 @@ -109,12 +112,12 @@
18  static void             free_cache(struct name_cache *cache);
19  static const char *     lookup_gname(struct bsdtar *bsdtar, gid_t gid);
20  static int              lookup_gname_helper(struct bsdtar *bsdtar,
21 -                            const char **name, id_t gid);
22 +                            const char **name, gid_t gid);
23  static void             lookup_hardlink(struct bsdtar *,
24                              struct archive_entry *entry, const struct stat *);
25  static const char *     lookup_uname(struct bsdtar *bsdtar, uid_t uid);
26  static int              lookup_uname_helper(struct bsdtar *bsdtar,
27 -                            const char **name, id_t uid);
28 +                            const char **name, uid_t uid);
29  static int              new_enough(struct bsdtar *, const char *path,
30                              time_t mtime_sec, int mtime_nsec);
31  static void             setup_acls(struct bsdtar *, struct archive_entry *,
32 @@ -1157,18 +1160,14 @@
33         }
34  }
35  
36 -/*
37 - * Lookup uid/gid from uname/gname, return NULL if no match.
38 - */
39  static const char *
40 -lookup_name(struct bsdtar *bsdtar, struct name_cache **name_cache_variable,
41 -    int (*lookup_fn)(struct bsdtar *, const char **, id_t), id_t id)
42 +lookup_uname(struct bsdtar *bsdtar, uid_t uid)
43  {
44 -       struct name_cache       *cache;
45 +       struct name_cache **name_cache_variable = &bsdtar->uname_cache;
46 +       struct name_cache *cache;
47         const char *name;
48         int slot;
49  
50 -
51         if (*name_cache_variable == NULL) {
52                 *name_cache_variable = malloc(sizeof(struct name_cache));
53                 if (*name_cache_variable == NULL)
54 @@ -1180,9 +1179,9 @@
55         cache = *name_cache_variable;
56         cache->probes++;
57  
58 -       slot = id % cache->size;
59 +       slot = uid % cache->size;
60         if (cache->cache[slot].name != NULL) {
61 -               if (cache->cache[slot].id == id) {
62 +               if (cache->cache[slot].id.uid == uid) {
63                         cache->hits++;
64                         if (cache->cache[slot].name == NO_NAME)
65                                 return (NULL);
66 @@ -1193,15 +1192,15 @@
67                 cache->cache[slot].name = NULL;
68         }
69  
70 -       if (lookup_fn(bsdtar, &name, id) == 0) {
71 +       if (lookup_uname_helper(bsdtar, &name, uid) == 0) {
72                 if (name == NULL || name[0] == '\0') {
73                         /* Cache the negative response. */
74                         cache->cache[slot].name = NO_NAME;
75 -                       cache->cache[slot].id = id;
76 +                       cache->cache[slot].id.uid = uid;
77                 } else {
78                         cache->cache[slot].name = strdup(name);
79                         if (cache->cache[slot].name != NULL) {
80 -                               cache->cache[slot].id = id;
81 +                               cache->cache[slot].id.uid = uid;
82                                 return (cache->cache[slot].name);
83                         }
84                         /*
85 @@ -1214,26 +1213,17 @@
86         return (NULL);
87  }
88  
89 -static const char *
90 -lookup_uname(struct bsdtar *bsdtar, uid_t uid)
91 -{
92 -       return (lookup_name(bsdtar, &bsdtar->uname_cache,
93 -                   &lookup_uname_helper, (id_t)uid));
94 -}
95 -
96  static int
97 -lookup_uname_helper(struct bsdtar *bsdtar, const char **name, id_t id)
98 +lookup_uname_helper(struct bsdtar *bsdtar __unused, const char **name, uid_t uid)
99  {
100         struct passwd   *pwent;
101  
102 -       (void)bsdtar; /* UNUSED */
103 -
104         errno = 0;
105 -       pwent = getpwuid((uid_t)id);
106 +       pwent = getpwuid(uid);
107         if (pwent == NULL) {
108                 *name = NULL;
109                 if (errno != 0)
110 -                       bsdtar_warnc(bsdtar, errno, "getpwuid(%d) failed", id);
111 +                       bsdtar_warnc(bsdtar, errno, "getpwuid(%d) failed", uid);
112                 return (errno);
113         }
114  
115 @@ -1244,23 +1234,69 @@
116  static const char *
117  lookup_gname(struct bsdtar *bsdtar, gid_t gid)
118  {
119 -       return (lookup_name(bsdtar, &bsdtar->gname_cache,
120 -                   &lookup_gname_helper, (id_t)gid));
121 +       struct name_cache **name_cache_variable = &bsdtar->gname_cache;
122 +       struct name_cache *cache;
123 +       const char *name;
124 +       int slot;
125 +
126 +       if (*name_cache_variable == NULL) {
127 +               *name_cache_variable = malloc(sizeof(struct name_cache));
128 +               if (*name_cache_variable == NULL)
129 +                       bsdtar_errc(bsdtar, 1, ENOMEM, "No more memory");
130 +               memset(*name_cache_variable, 0, sizeof(struct name_cache));
131 +               (*name_cache_variable)->size = name_cache_size;
132 +       }
133 +
134 +       cache = *name_cache_variable;
135 +       cache->probes++;
136 +
137 +       slot = gid % cache->size;
138 +       if (cache->cache[slot].name != NULL) {
139 +               if (cache->cache[slot].id.gid == gid) {
140 +                       cache->hits++;
141 +                       if (cache->cache[slot].name == NO_NAME)
142 +                               return (NULL);
143 +                       return (cache->cache[slot].name);
144 +               }
145 +               if (cache->cache[slot].name != NO_NAME)
146 +                       free((void *)(uintptr_t)cache->cache[slot].name);
147 +               cache->cache[slot].name = NULL;
148 +       }
149 +
150 +       if (lookup_gname_helper(bsdtar, &name, gid) == 0) {
151 +               if (name == NULL || name[0] == '\0') {
152 +                       /* Cache the negative response. */
153 +                       cache->cache[slot].name = NO_NAME;
154 +                       cache->cache[slot].id.gid = gid;
155 +               } else {
156 +                       cache->cache[slot].name = strdup(name);
157 +                       if (cache->cache[slot].name != NULL) {
158 +                               cache->cache[slot].id.gid = gid;
159 +                               return (cache->cache[slot].name);
160 +                       }
161 +                       /*
162 +                        * Conveniently, NULL marks an empty slot, so
163 +                        * if the strdup() fails, we've just failed to
164 +                        * cache it.  No recovery necessary.
165 +                        */
166 +               }
167 +       }
168 +       return (NULL);
169  }
170  
171  static int
172 -lookup_gname_helper(struct bsdtar *bsdtar, const char **name, id_t id)
173 +lookup_gname_helper(struct bsdtar *bsdtar, const char **name, gid_t gid)
174  {
175         struct group    *grent;
176  
177         (void)bsdtar; /* UNUSED */
178  
179         errno = 0;
180 -       grent = getgrgid((gid_t)id);
181 +       grent = getgrgid(gid);
182         if (grent == NULL) {
183                 *name = NULL;
184                 if (errno != 0)
185 -                       bsdtar_warnc(bsdtar, errno, "getgrgid(%d) failed", id);
186 +                       bsdtar_warnc(bsdtar, errno, "getgrgid(%d) failed", gid);
187                 return (errno);
188         }
189