Rev 32 | Go to most recent revision | Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 23 | magnus | 1 | Author: Svante Signell <svante.signell@telia.com> | 
| 2 | Author: Petter Reinholdtsen <pere@hungry.com> | ||
| 3 | Author: Magnus Holmgren <magnus@debian.org> | ||
| 4 | Bug-Debian: http://bugs.debian.org/657116 | ||
| 5 | Description: Fix FTBFS on Hurd by dynamically allocating path names. | ||
| 6 | Depends on no_static_buffers.patch, which introduced the th_pathname field. | ||
| 7 | |||
| 8 | --- a/compat/basename.c | ||
| 9 | +++ b/compat/basename.c | ||
| 10 | @@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: basenam | ||
| 11 | #include <errno.h> | ||
| 12 | #include <string.h> | ||
| 13 | #include <sys/param.h> | ||
| 14 | +#include <stdlib.h> | ||
| 15 | |||
| 16 | char * | ||
| 17 | openbsd_basename(path) | ||
| 18 | const char *path; | ||
| 19 |  { | ||
| 20 | -       static char bname[MAXPATHLEN]; | ||
| 21 | +       static char *bname = NULL; | ||
| 22 | +       static size_t allocated = 0; | ||
| 23 | register const char *endp, *startp; | ||
| 24 | +       int len = 0; | ||
| 25 | + | ||
| 26 | +       if (!allocated) { | ||
| 27 | +               allocated = 64; | ||
| 28 | +               bname = malloc(allocated); | ||
| 29 | +               if (!bname) { | ||
| 30 | +                       allocated = 0; | ||
| 31 | +                       return NULL; | ||
| 32 | +               } | ||
| 33 | +       } | ||
| 34 | |||
| 35 | /* Empty or NULL string gets treated as "." */ | ||
| 36 | if (path == NULL || *path == '\0') { | ||
| 37 | @@ -64,11 +76,19 @@ openbsd_basename(path) | ||
| 38 | while (startp > path && *(startp - 1) != '/') | ||
| 39 | startp--; | ||
| 40 | |||
| 41 | -       if (endp - startp + 1 > sizeof(bname)) { | ||
| 42 | -               errno = ENAMETOOLONG; | ||
| 43 | -               return(NULL); | ||
| 44 | +       len = endp - startp + 1; | ||
| 45 | + | ||
| 46 | +       if (len + 1 > allocated) { | ||
| 47 | +               size_t new_allocated = 2*(len+1); | ||
| 48 | +               void *new_bname = malloc(new_allocated); | ||
| 49 | +               if (!new_bname) | ||
| 50 | +                       return NULL; | ||
| 51 | +               allocated = new_allocated; | ||
| 52 | +               free(bname); | ||
| 53 | +               bname = new_bname; | ||
| 54 |         } | ||
| 55 | -       (void)strncpy(bname, startp, endp - startp + 1); | ||
| 56 | -       bname[endp - startp + 1] = '\0'; | ||
| 57 | + | ||
| 58 | +       (void)strncpy(bname, startp, len); | ||
| 59 | +       bname[len] = '\0'; | ||
| 60 | return(bname); | ||
| 61 |  } | ||
| 62 | --- a/compat/dirname.c | ||
| 63 | +++ b/compat/dirname.c | ||
| 64 | @@ -34,13 +34,25 @@ static char rcsid[] = "$OpenBSD: dirname | ||
| 65 | #include <errno.h> | ||
| 66 | #include <string.h> | ||
| 67 | #include <sys/param.h> | ||
| 68 | +#include <stdlib.h> | ||
| 69 | |||
| 70 | char * | ||
| 71 | openbsd_dirname(path) | ||
| 72 | const char *path; | ||
| 73 |  { | ||
| 74 | -       static char bname[MAXPATHLEN]; | ||
| 75 | +       static char *bname = NULL; | ||
| 76 | +       static size_t allocated = 0; | ||
| 77 | register const char *endp; | ||
| 78 | +       int len; | ||
| 79 | + | ||
| 80 | +       if (!allocated) { | ||
| 81 | +               allocated = 64; | ||
| 82 | +               bname = malloc(allocated); | ||
| 83 | +               if (!bname) { | ||
| 84 | +                       allocated = 0; | ||
| 85 | +                       return NULL; | ||
| 86 | +               } | ||
| 87 | +       } | ||
| 88 | |||
| 89 | /* Empty or NULL string gets treated as "." */ | ||
| 90 | if (path == NULL || *path == '\0') { | ||
| 91 | --- a/lib/append.c | ||
| 92 | +++ b/lib/append.c | ||
| 93 | @@ -38,7 +38,7 @@ typedef struct tar_dev tar_dev_t; | ||
| 94 | struct tar_ino | ||
| 95 |  { | ||
| 96 | ino_t ti_ino; | ||
| 97 | -       char ti_name[MAXPATHLEN]; | ||
| 98 | +       char ti_name[]; | ||
| 99 |  }; | ||
| 100 | typedef struct tar_ino tar_ino_t; | ||
| 101 | |||
| 102 | @@ -61,7 +61,7 @@ tar_append_file(TAR *t, const char *real | ||
| 103 | libtar_hashptr_t hp; | ||
| 104 | tar_dev_t *td = NULL; | ||
| 105 | tar_ino_t *ti = NULL; | ||
| 106 | -       char path[MAXPATHLEN]; | ||
| 107 | +       char *path = NULL; | ||
| 108 | |||
| 109 | #ifdef DEBUG | ||
| 110 | printf("==> tar_append_file(TAR=0x%lx (\"%s\"), realname=\"%s\", " | ||
| 111 | @@ -126,34 +126,39 @@ tar_append_file(TAR *t, const char *real | ||
| 112 |         } | ||
| 113 | else | ||
| 114 |         { | ||
| 115 | +               const char *name; | ||
| 116 | #ifdef DEBUG | ||
| 117 | printf("+++ adding entry: device (0x%lx,0x%lx), inode %ld " | ||
| 118 | "(\"%s\")...\n", major(s.st_dev), minor(s.st_dev), | ||
| 119 |                        s.st_ino, realname); | ||
| 120 | #endif | ||
| 121 | -               ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t)); | ||
| 122 | +               name = savename ? savename : realname; | ||
| 123 | +               ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t) + strlen(name) + 1); | ||
| 124 | if (ti == NULL) | ||
| 125 |                         return -1; | ||
| 126 | ti->ti_ino = s.st_ino; | ||
| 127 | -               snprintf(ti->ti_name, sizeof(ti->ti_name), "%s", | ||
| 128 | -                        savename ? savename : realname); | ||
| 129 | +               snprintf(ti->ti_name, strlen(name) + 1, "%s", name); | ||
| 130 | libtar_hash_add(td->td_h, ti); | ||
| 131 |         } | ||
| 132 | |||
| 133 | /* check if it's a symlink */ | ||
| 134 | if (TH_ISSYM(t)) | ||
| 135 |         { | ||
| 136 | -               i = readlink(realname, path, sizeof(path)); | ||
| 137 | +               if ((path = malloc(s.st_size + 1)) == NULL) | ||
| 138 | +                       return -1; | ||
| 139 | +               i = readlink(realname, path, s.st_size); | ||
| 140 | if (i == -1) | ||
| 141 | +               { | ||
| 142 | +                       free(path); | ||
| 143 |                         return -1; | ||
| 144 | -               if (i >= MAXPATHLEN) | ||
| 145 | -                       i = MAXPATHLEN - 1; | ||
| 146 | +               } | ||
| 147 | path[i] = '\0'; | ||
| 148 | #ifdef DEBUG | ||
| 149 | printf(" tar_append_file(): encoding symlink \"%s\" -> " | ||
| 150 |                        "\"%s\"...\n", realname, path); | ||
| 151 | #endif | ||
| 152 | th_set_link(t, path); | ||
| 153 | +               free(path); | ||
| 154 |         } | ||
| 155 | |||
| 156 | /* print file info */ | ||
| 157 | --- a/lib/decode.c | ||
| 158 | +++ b/lib/decode.c | ||
| 159 | @@ -29,10 +29,13 @@ th_get_pathname(TAR *t) | ||
| 160 | if (t->th_buf.gnu_longname) | ||
| 161 | return t->th_buf.gnu_longname; | ||
| 162 | |||
| 163 | +       size_t pathlen = | ||
| 164 | +         strlen(t->th_buf.prefix) + strlen(t->th_buf.name) + 2; | ||
| 165 | + | ||
| 166 | /* allocate the th_pathname buffer if not already */ | ||
| 167 | if (t->th_pathname == NULL) | ||
| 168 |         { | ||
| 169 | -               t->th_pathname = malloc(MAXPATHLEN * sizeof(char)); | ||
| 170 | +               t->th_pathname = malloc(pathlen); | ||
| 171 | if (t->th_pathname == NULL) | ||
| 172 | /* out of memory */ | ||
| 173 | return NULL; | ||
| 174 | @@ -40,11 +43,11 @@ th_get_pathname(TAR *t) | ||
| 175 | |||
| 176 | if (t->th_buf.prefix[0] == '\0') | ||
| 177 |         { | ||
| 178 | -               snprintf(t->th_pathname, MAXPATHLEN, "%.100s", t->th_buf.name); | ||
| 179 | +               snprintf(t->th_pathname, pathlen, "%.100s", t->th_buf.name); | ||
| 180 |         } | ||
| 181 | else | ||
| 182 |         { | ||
| 183 | -               snprintf(t->th_pathname, MAXPATHLEN, "%.155s/%.100s", | ||
| 184 | +               snprintf(t->th_pathname, pathlen, "%.155s/%.100s", | ||
| 185 |                          t->th_buf.prefix, t->th_buf.name); | ||
| 186 |         } | ||
| 187 | |||
| 188 | --- a/lib/util.c | ||
| 189 | +++ b/lib/util.c | ||
| 190 | @@ -15,6 +15,7 @@ | ||
| 191 | #include <stdio.h> | ||
| 192 | #include <sys/param.h> | ||
| 193 | #include <errno.h> | ||
| 194 | +#include <stdlib.h> | ||
| 195 | |||
| 196 | #ifdef STDC_HEADERS | ||
| 197 | # include <string.h> | ||
| 198 | @@ -25,13 +26,15 @@ | ||
| 199 | int | ||
| 200 | path_hashfunc(char *key, int numbuckets) | ||
| 201 |  { | ||
| 202 | -       char buf[MAXPATHLEN]; | ||
| 203 | +       char *buf; | ||
| 204 | char *p; | ||
| 205 | +       int i; | ||
| 206 | |||
| 207 | -       strcpy(buf, key); | ||
| 208 | +       buf = strdup(key); | ||
| 209 | p = basename(buf); | ||
| 210 | - | ||
| 211 | -       return (((unsigned int)p[0]) % numbuckets); | ||
| 212 | +       i = ((unsigned int)p[0]) % numbuckets; | ||
| 213 | +       free(buf); | ||
| 214 | +       return (i); | ||
| 215 |  } | ||
| 216 | |||
| 217 | |||
| 218 | @@ -77,15 +80,26 @@ ino_hash(ino_t *inode) | ||
| 219 | int | ||
| 220 | mkdirhier(char *path) | ||
| 221 |  { | ||
| 222 | -       char src[MAXPATHLEN], dst[MAXPATHLEN] = ""; | ||
| 223 | -       char *dirp, *nextp = src; | ||
| 224 | -       int retval = 1; | ||
| 225 | +       char *src, *dst = NULL; | ||
| 226 | +       char *dirp, *nextp = NULL; | ||
| 227 | +       int retval = 1, len; | ||
| 228 | + | ||
| 229 | +       len = strlen(path); | ||
| 230 | +       if ((src = strdup(path)) == NULL) | ||
| 231 | +       { | ||
| 232 | +               errno = ENOMEM; | ||
| 233 | +               return -1; | ||
| 234 | +       } | ||
| 235 | +       nextp = src; | ||
| 236 | |||
| 237 | -       if (strlcpy(src, path, sizeof(src)) > sizeof(src)) | ||
| 238 | +       /* Make room for // with absolute paths */ | ||
| 239 | +       if ((dst = malloc(len + 2)) == NULL) | ||
| 240 |         { | ||
| 241 | -               errno = ENAMETOOLONG; | ||
| 242 | +               free(src); | ||
| 243 | +               errno = ENOMEM; | ||
| 244 |                 return -1; | ||
| 245 |         } | ||
| 246 | +       dst[0] = '\0'; | ||
| 247 | |||
| 248 | if (path[0] == '/') | ||
| 249 | strcpy(dst, "/"); | ||
| 250 | @@ -102,12 +116,18 @@ mkdirhier(char *path) | ||
| 251 | if (mkdir(dst, 0777) == -1) | ||
| 252 |                 { | ||
| 253 | if (errno != EEXIST) | ||
| 254 | +                       { | ||
| 255 | +                               free(src); | ||
| 256 | +                               free(dst); | ||
| 257 |                                 return -1; | ||
| 258 | +                       } | ||
| 259 |                 } | ||
| 260 | else | ||
| 261 |                         retval = 0; | ||
| 262 |         } | ||
| 263 | |||
| 264 | +       free(src); | ||
| 265 | +       free(dst); | ||
| 266 | return retval; | ||
| 267 |  } | ||
| 268 | |||
| 269 | --- a/lib/wrapper.c | ||
| 270 | +++ b/lib/wrapper.c | ||
| 271 | @@ -16,18 +16,18 @@ | ||
| 272 | #include <sys/param.h> | ||
| 273 | #include <dirent.h> | ||
| 274 | #include <errno.h> | ||
| 275 | +#include <stdlib.h> | ||
| 276 | |||
| 277 | #ifdef STDC_HEADERS | ||
| 278 | # include <string.h> | ||
| 279 | #endif | ||
| 280 | |||
| 281 | - | ||
| 282 | int | ||
| 283 | tar_extract_glob(TAR *t, char *globname, char *prefix) | ||
| 284 |  { | ||
| 285 | char *filename; | ||
| 286 | -       char buf[MAXPATHLEN]; | ||
| 287 | -       int i; | ||
| 288 | +       char *buf = NULL; | ||
| 289 | +       int i, len; | ||
| 290 | |||
| 291 | while ((i = th_read(t)) == 0) | ||
| 292 |         { | ||
| 293 | @@ -41,11 +41,25 @@ tar_extract_glob(TAR *t, char *globname, | ||
| 294 | if (t->options & TAR_VERBOSE) | ||
| 295 | th_print_long_ls(t); | ||
| 296 | if (prefix != NULL) | ||
| 297 | -                       snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); | ||
| 298 | +               { | ||
| 299 | +                       len = strlen(prefix) + 1 + strlen(filename); | ||
| 300 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 301 | +                               return -1; | ||
| 302 | +                       sprintf(buf, "%s/%s", prefix, filename); | ||
| 303 | +               } | ||
| 304 | else | ||
| 305 | -                       strlcpy(buf, filename, sizeof(buf)); | ||
| 306 | +               { | ||
| 307 | +                       len = strlen(filename); | ||
| 308 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 309 | +                               return -1; | ||
| 310 | +                       strcpy(buf, filename); | ||
| 311 | +               } | ||
| 312 | if (tar_extract_file(t, buf) != 0) | ||
| 313 | +               { | ||
| 314 | +                       free(buf); | ||
| 315 |                         return -1; | ||
| 316 | +               } | ||
| 317 | +               free(buf); | ||
| 318 |         } | ||
| 319 | |||
| 320 | return (i == 1 ? 0 : -1); | ||
| 321 | @@ -56,8 +70,9 @@ int | ||
| 322 | tar_extract_all(TAR *t, char *prefix) | ||
| 323 |  { | ||
| 324 | char *filename; | ||
| 325 | -       char buf[MAXPATHLEN]; | ||
| 326 | -       int i; | ||
| 327 | +       char *buf = NULL; | ||
| 328 | +       size_t bufsize = 0; | ||
| 329 | +       int i, len; | ||
| 330 | |||
| 331 | #ifdef DEBUG | ||
| 332 | printf("==> tar_extract_all(TAR *t, \"%s\")\n", | ||
| 333 | @@ -69,19 +84,34 @@ tar_extract_all(TAR *t, char *prefix) | ||
| 334 | #ifdef DEBUG | ||
| 335 | puts(" tar_extract_all(): calling th_get_pathname()"); | ||
| 336 | #endif | ||
| 337 | + | ||
| 338 | filename = th_get_pathname(t); | ||
| 339 | if (t->options & TAR_VERBOSE) | ||
| 340 | th_print_long_ls(t); | ||
| 341 | if (prefix != NULL) | ||
| 342 | -                       snprintf(buf, sizeof(buf), "%s/%s", prefix, filename); | ||
| 343 | +               { | ||
| 344 | +                       len = strlen(prefix) + 1 + strlen(filename); | ||
| 345 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 346 | +                               return -1; | ||
| 347 | +                       sprintf(buf, "%s/%s", prefix, filename); | ||
| 348 | +               } | ||
| 349 | else | ||
| 350 | -                       strlcpy(buf, filename, sizeof(buf)); | ||
| 351 | +               { | ||
| 352 | +                       len = strlen(filename); | ||
| 353 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 354 | +                               return -1; | ||
| 355 | +                       strcpy(buf, filename); | ||
| 356 | +               } | ||
| 357 | #ifdef DEBUG | ||
| 358 | printf(" tar_extract_all(): calling tar_extract_file(t, " | ||
| 359 | "\"%s\")\n", buf); | ||
| 360 | #endif | ||
| 361 | if (tar_extract_file(t, buf) != 0) | ||
| 362 | +               { | ||
| 363 | +                       free(buf); | ||
| 364 |                         return -1; | ||
| 365 | +               } | ||
| 366 | +               free(buf); | ||
| 367 |         } | ||
| 368 | |||
| 369 | return (i == 1 ? 0 : -1); | ||
| 370 | @@ -91,11 +121,14 @@ tar_extract_all(TAR *t, char *prefix) | ||
| 371 | int | ||
| 372 | tar_append_tree(TAR *t, char *realdir, char *savedir) | ||
| 373 |  { | ||
| 374 | -       char realpath[MAXPATHLEN]; | ||
| 375 | -       char savepath[MAXPATHLEN]; | ||
| 376 | +       char *realpath = NULL; | ||
| 377 | +       size_t realpathsize = 0; | ||
| 378 | +       char *savepath = NULL; | ||
| 379 | +       size_t savepathsize = 0; | ||
| 380 | struct dirent *dent; | ||
| 381 | DIR *dp; | ||
| 382 | struct stat s; | ||
| 383 | +       int len; | ||
| 384 | |||
| 385 | #ifdef DEBUG | ||
| 386 | printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n", | ||
| 387 | @@ -122,11 +155,19 @@ tar_append_tree(TAR *t, char *realdir, c | ||
| 388 | strcmp(dent->d_name, "..") == 0) | ||
| 389 | continue; | ||
| 390 | |||
| 391 | -               snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, | ||
| 392 | +               len = strlen(realdir) + 1 + strlen(dent->d_name); | ||
| 393 | +               if ((realpath = malloc(len + 1)) == NULL) | ||
| 394 | +                       return -1; | ||
| 395 | +               snprintf(realpath, len + 1, "%s/%s", realdir, | ||
| 396 |                          dent->d_name); | ||
| 397 | if (savedir) | ||
| 398 | -                       snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, | ||
| 399 | +               { | ||
| 400 | +                       len = strlen(savedir) + 1 + strlen(dent->d_name); | ||
| 401 | +                       if ((savepath = malloc(len + 1)) == NULL) | ||
| 402 | +                               return -1; | ||
| 403 | +                       snprintf(realpath, len + 1, "%s/%s", savedir, | ||
| 404 |                                  dent->d_name); | ||
| 405 | +               } | ||
| 406 | |||
| 407 | if (lstat(realpath, &s) != 0) | ||
| 408 |                         return -1; | ||
| 409 | @@ -135,13 +176,23 @@ tar_append_tree(TAR *t, char *realdir, c | ||
| 410 |                 { | ||
| 411 | if (tar_append_tree(t, realpath, | ||
| 412 | (savedir ? savepath : NULL)) != 0) | ||
| 413 | +                       { | ||
| 414 | +                               free(realpath); | ||
| 415 | +                               free(savepath); | ||
| 416 |                                 return -1; | ||
| 417 | +                       } | ||
| 418 | continue; | ||
| 419 |                 } | ||
| 420 | |||
| 421 | if (tar_append_file(t, realpath, | ||
| 422 | (savedir ? savepath : NULL)) != 0) | ||
| 423 | +               { | ||
| 424 | +                       free(realpath); | ||
| 425 | +                       free(savepath); | ||
| 426 |                         return -1; | ||
| 427 | +               } | ||
| 428 | +               free(realpath); | ||
| 429 | +               free(savepath); | ||
| 430 |         } | ||
| 431 | |||
| 432 | closedir(dp); | ||
| 433 | --- a/libtar/libtar.c | ||
| 434 | +++ b/libtar/libtar.c | ||
| 435 | @@ -111,8 +111,9 @@ create(char *tarfile, char *rootdir, lib | ||
| 436 |  { | ||
| 437 | TAR *t; | ||
| 438 | char *pathname; | ||
| 439 | -       char buf[MAXPATHLEN]; | ||
| 440 | +       char *buf = NULL; | ||
| 441 | libtar_listptr_t lp; | ||
| 442 | +       int len; | ||
| 443 | |||
| 444 | if (tar_open(&t, tarfile, | ||
| 445 | #ifdef HAVE_LIBZ | ||
| 446 | @@ -133,17 +134,29 @@ create(char *tarfile, char *rootdir, lib | ||
| 447 |         { | ||
| 448 | pathname = (char *)libtar_listptr_data(&lp); | ||
| 449 | if (pathname[0] != '/' && rootdir != NULL) | ||
| 450 | -                       snprintf(buf, sizeof(buf), "%s/%s", rootdir, pathname); | ||
| 451 | +               { | ||
| 452 | +                       len = strlen(rootdir) + 1 + strlen(pathname); | ||
| 453 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 454 | +                               return -1; | ||
| 455 | +                       snprintf(buf, len + 1, "%s/%s", rootdir, pathname); | ||
| 456 | +               } | ||
| 457 | else | ||
| 458 | -                       strlcpy(buf, pathname, sizeof(buf)); | ||
| 459 | +               { | ||
| 460 | +                       len = strlen(pathname); | ||
| 461 | +                       if ((buf = malloc(len + 1)) == NULL) | ||
| 462 | +                               return -1; | ||
| 463 | +                       strlcpy(buf, pathname, len + 1); | ||
| 464 | +               } | ||
| 465 | if (tar_append_tree(t, buf, pathname) != 0) | ||
| 466 |                 { | ||
| 467 |                         fprintf(stderr, | ||
| 468 | "tar_append_tree(\"%s\", \"%s\"): %s\n", buf, | ||
| 469 | pathname, strerror(errno)); | ||
| 470 | tar_close(t); | ||
| 471 | +                       free(buf); | ||
| 472 |                         return -1; | ||
| 473 |                 } | ||
| 474 | +               free(buf); | ||
| 475 |         } | ||
| 476 | |||
| 477 | if (tar_append_eof(t) != 0) |