00001
00005 #include "system.h"
00006
00007 #if defined(HAVE_PTHREAD_H) && !defined(__LCLINT__)
00008 #include <pthread.h>
00009 #endif
00010
00011 #include <rpmio_internal.h>
00012
00013 #define _RPMDAV_INTERNAL
00014 #include <rpmdav.h>
00015
00016 #include "ugid.h"
00017 #include "debug.h"
00018
00019
00020
00021
00022
00023
00024 static int ftpMkdir(const char * path, mode_t mode)
00025
00026
00027 {
00028 int rc;
00029 if ((rc = ftpCmd("MKD", path, NULL)) != 0)
00030 return rc;
00031 #if NOTYET
00032 { char buf[20];
00033 sprintf(buf, " 0%o", mode);
00034 (void) ftpCmd("SITE CHMOD", path, buf);
00035 }
00036 #endif
00037 return rc;
00038 }
00039
00040 static int ftpChdir(const char * path)
00041
00042
00043 {
00044 return ftpCmd("CWD", path, NULL);
00045 }
00046
00047 static int ftpRmdir(const char * path)
00048
00049
00050 {
00051 return ftpCmd("RMD", path, NULL);
00052 }
00053
00054 static int ftpRename(const char * oldpath, const char * newpath)
00055
00056
00057 {
00058 int rc;
00059 if ((rc = ftpCmd("RNFR", oldpath, NULL)) != 0)
00060 return rc;
00061 return ftpCmd("RNTO", newpath, NULL);
00062 }
00063
00064 static int ftpUnlink(const char * path)
00065
00066
00067 {
00068 return ftpCmd("DELE", path, NULL);
00069 }
00070
00071
00072 int Mkdir (const char * path, mode_t mode)
00073 {
00074 const char * lpath;
00075 int ut = urlPath(path, &lpath);
00076
00077 switch (ut) {
00078 case URL_IS_FTP:
00079 return ftpMkdir(path, mode);
00080 break;
00081 case URL_IS_PATH:
00082 path = lpath;
00083
00084 case URL_IS_UNKNOWN:
00085 break;
00086 case URL_IS_DASH:
00087 case URL_IS_HKP:
00088 default:
00089 return -2;
00090 break;
00091 }
00092 return mkdir(path, mode);
00093 }
00094
00095 int Chdir (const char * path)
00096 {
00097 const char * lpath;
00098 int ut = urlPath(path, &lpath);
00099
00100 switch (ut) {
00101 case URL_IS_FTP:
00102 return ftpChdir(path);
00103 break;
00104 case URL_IS_PATH:
00105 path = lpath;
00106
00107 case URL_IS_UNKNOWN:
00108 break;
00109 case URL_IS_DASH:
00110 case URL_IS_HKP:
00111 default:
00112 errno = EINVAL;
00113 return -2;
00114 break;
00115 }
00116 return chdir(path);
00117 }
00118
00119 int Rmdir (const char * path)
00120 {
00121 const char * lpath;
00122 int ut = urlPath(path, &lpath);
00123
00124 switch (ut) {
00125 case URL_IS_FTP:
00126 return ftpRmdir(path);
00127 break;
00128 case URL_IS_PATH:
00129 path = lpath;
00130
00131 case URL_IS_UNKNOWN:
00132 break;
00133 case URL_IS_DASH:
00134 case URL_IS_HKP:
00135 default:
00136 return -2;
00137 break;
00138 }
00139 return rmdir(path);
00140 }
00141
00142
00143 const char * _chroot_prefix = NULL;
00144
00145 int Chroot(const char * path)
00146 {
00147 const char * lpath;
00148 int ut = urlPath(path, &lpath);
00149
00150 if (_rpmio_debug)
00151 fprintf(stderr, "*** Chroot(%s)\n", path);
00152 switch (ut) {
00153 case URL_IS_PATH:
00154 path = lpath;
00155
00156 case URL_IS_UNKNOWN:
00157 break;
00158 case URL_IS_DASH:
00159 case URL_IS_HKP:
00160 case URL_IS_FTP:
00161 case URL_IS_HTTPS:
00162 case URL_IS_HTTP:
00163 default:
00164 errno = EINVAL;
00165 return -2;
00166 break;
00167 }
00168
00169 _chroot_prefix = _free(_chroot_prefix);
00170 if (strcmp(path, "."))
00171 _chroot_prefix = rpmGetPath(path, NULL);
00172
00173
00174 return chroot(path);
00175
00176 }
00177
00178 int Open(const char * path, int flags, mode_t mode)
00179 {
00180 const char * lpath;
00181 int ut = urlPath(path, &lpath);
00182 int fdno;
00183
00184 if (_rpmio_debug)
00185 fprintf(stderr, "*** Open(%s, 0x%x, 0%o)\n", path, flags, mode);
00186 switch (ut) {
00187 case URL_IS_PATH:
00188 path = lpath;
00189
00190 case URL_IS_UNKNOWN:
00191 break;
00192 case URL_IS_DASH:
00193 case URL_IS_HKP:
00194 case URL_IS_FTP:
00195 case URL_IS_HTTPS:
00196 case URL_IS_HTTP:
00197 default:
00198 errno = EINVAL;
00199 return -2;
00200 break;
00201 }
00202
00203 if (_chroot_prefix && _chroot_prefix[0] == '/' && _chroot_prefix[1] != '\0')
00204 {
00205 size_t nb = strlen(_chroot_prefix);
00206 size_t ob = strlen(path);
00207 while (nb > 0 && _chroot_prefix[nb-1] == '/')
00208 nb--;
00209 if (ob > nb && !strncmp(path, _chroot_prefix, nb) && path[nb] == '/')
00210 path += nb;
00211 }
00212 #ifdef NOTYET
00213 if (mode == 0)
00214 mode = 0644;
00215 #endif
00216 fdno = open(path, flags, mode);
00217
00218 if (fdno < 0 && errno == ENOENT) {
00219 const char *dbpath = rpmExpand("%{_dbpath}", "/", NULL);
00220 const char *fn = strstr(path + 1, dbpath);
00221 if (fn)
00222 fdno = open(fn, flags, mode);
00223 if (dbpath)
00224 dbpath = _free(dbpath);
00225 }
00226 return fdno;
00227 }
00228
00229
00230
00231 int Rename (const char * oldpath, const char * newpath)
00232 {
00233 const char *oe = NULL;
00234 const char *ne = NULL;
00235 int oldut, newut;
00236
00237
00238 if (!strcmp(oldpath, newpath)) return 0;
00239
00240 oldut = urlPath(oldpath, &oe);
00241 switch (oldut) {
00242 case URL_IS_FTP:
00243 case URL_IS_PATH:
00244 case URL_IS_UNKNOWN:
00245 break;
00246 case URL_IS_DASH:
00247 case URL_IS_HKP:
00248 default:
00249 return -2;
00250 break;
00251 }
00252
00253 newut = urlPath(newpath, &ne);
00254 switch (newut) {
00255 case URL_IS_FTP:
00256 if (_rpmio_debug)
00257 fprintf(stderr, "*** rename old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
00258 if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
00259 !xstrncasecmp(oldpath, newpath, (oe - oldpath))))
00260 return -2;
00261 return ftpRename(oldpath, newpath);
00262 break;
00263 case URL_IS_HTTPS:
00264 case URL_IS_HTTP:
00265 case URL_IS_PATH:
00266 oldpath = oe;
00267 newpath = ne;
00268 break;
00269 case URL_IS_UNKNOWN:
00270 break;
00271 case URL_IS_DASH:
00272 case URL_IS_HKP:
00273 default:
00274 return -2;
00275 break;
00276 }
00277 return rename(oldpath, newpath);
00278 }
00279
00280 int Link (const char * oldpath, const char * newpath)
00281 {
00282 const char *oe = NULL;
00283 const char *ne = NULL;
00284 int oldut, newut;
00285
00286 oldut = urlPath(oldpath, &oe);
00287 switch (oldut) {
00288 case URL_IS_HTTPS:
00289 case URL_IS_HTTP:
00290 case URL_IS_FTP:
00291 case URL_IS_PATH:
00292 case URL_IS_UNKNOWN:
00293 break;
00294 case URL_IS_DASH:
00295 case URL_IS_HKP:
00296 default:
00297 return -2;
00298 break;
00299 }
00300
00301 newut = urlPath(newpath, &ne);
00302 switch (newut) {
00303 case URL_IS_HTTPS:
00304 case URL_IS_HTTP:
00305 case URL_IS_FTP:
00306 case URL_IS_PATH:
00307 if (_rpmio_debug)
00308 fprintf(stderr, "*** link old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
00309 if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
00310 !xstrncasecmp(oldpath, newpath, (oe - oldpath))))
00311 return -2;
00312 oldpath = oe;
00313 newpath = ne;
00314 break;
00315 case URL_IS_UNKNOWN:
00316 break;
00317 case URL_IS_DASH:
00318 case URL_IS_HKP:
00319 default:
00320 return -2;
00321 break;
00322 }
00323 return link(oldpath, newpath);
00324 }
00325
00326
00327
00328 int Unlink(const char * path) {
00329 const char * lpath;
00330 int ut = urlPath(path, &lpath);
00331
00332 switch (ut) {
00333 case URL_IS_FTP:
00334 return ftpUnlink(path);
00335 break;
00336 case URL_IS_PATH:
00337 path = lpath;
00338
00339 case URL_IS_UNKNOWN:
00340 break;
00341 case URL_IS_DASH:
00342 case URL_IS_HKP:
00343 default:
00344 return -2;
00345 break;
00346 }
00347 return unlink(path);
00348 }
00349
00350
00351
00352 #define g_strdup xstrdup
00353 #define g_free free
00354
00355
00356
00357
00358
00359 static int current_mday;
00360
00361 static int current_mon;
00362
00363 static int current_year;
00364
00365
00366 #define MAXCOLS 30
00367
00368
00369 static char *columns [MAXCOLS];
00370
00371 static int column_ptr [MAXCOLS];
00372
00373
00374 static int
00375 vfs_split_text (char *p)
00376
00377
00378 {
00379 char *original = p;
00380 int numcols;
00381
00382
00383 for (numcols = 0; *p && numcols < MAXCOLS; numcols++){
00384 while (*p == ' ' || *p == '\r' || *p == '\n'){
00385 *p = 0;
00386 p++;
00387 }
00388 columns [numcols] = p;
00389 column_ptr [numcols] = p - original;
00390 while (*p && *p != ' ' && *p != '\r' && *p != '\n')
00391 p++;
00392 }
00393 return numcols;
00394 }
00395
00396
00397
00398 static int
00399 is_num (int idx)
00400
00401 {
00402 if (!columns [idx] || columns [idx][0] < '0' || columns [idx][0] > '9')
00403 return 0;
00404 return 1;
00405 }
00406
00407
00408
00409 static int
00410 is_dos_date( const char *str)
00411
00412 {
00413 if (str != NULL && strlen(str) == 8 &&
00414 str[2] == str[5] && strchr("\\-/", (int)str[2]) != NULL)
00415 return 1;
00416 return 0;
00417 }
00418
00419
00420 static int
00421 is_week ( const char * str, struct tm * tim)
00422
00423 {
00424 static const char * week = "SunMonTueWedThuFriSat";
00425 const char * pos;
00426
00427
00428 if (str != NULL && (pos=strstr(week, str)) != NULL) {
00429
00430 if (tim != NULL)
00431 tim->tm_wday = (pos - week)/3;
00432 return 1;
00433 }
00434 return 0;
00435 }
00436
00437 static int
00438 is_month ( const char * str, struct tm * tim)
00439
00440 {
00441 static const char * month = "JanFebMarAprMayJunJulAugSepOctNovDec";
00442 const char * pos;
00443
00444
00445 if (str != NULL && (pos = strstr(month, str)) != NULL) {
00446
00447 if (tim != NULL)
00448 tim->tm_mon = (pos - month)/3;
00449 return 1;
00450 }
00451 return 0;
00452 }
00453
00454 static int
00455 is_time ( const char * str, struct tm * tim)
00456
00457 {
00458 const char * p, * p2;
00459
00460 if (str != NULL && (p = strchr(str, ':')) && (p2 = strrchr(str, ':'))) {
00461 if (p != p2) {
00462 if (sscanf (str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min, &tim->tm_sec) != 3)
00463 return 0;
00464 } else {
00465 if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
00466 return 0;
00467 }
00468 } else
00469 return 0;
00470
00471 return 1;
00472 }
00473
00474 static int is_year( const char * str, struct tm * tim)
00475
00476 {
00477 long year;
00478
00479 if (str == NULL)
00480 return 0;
00481
00482 if (strchr(str,':'))
00483 return 0;
00484
00485 if (strlen(str) != 4)
00486 return 0;
00487
00488 if (sscanf(str, "%ld", &year) != 1)
00489 return 0;
00490
00491 if (year < 1900 || year > 3000)
00492 return 0;
00493
00494 tim->tm_year = (int) (year - 1900);
00495
00496 return 1;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 static int
00506 vfs_parse_filetype (char c)
00507
00508 {
00509 switch (c) {
00510 case 'd': return S_IFDIR;
00511 case 'b': return S_IFBLK;
00512 case 'c': return S_IFCHR;
00513 case 'l': return S_IFLNK;
00514 case 's':
00515 #ifdef IS_IFSOCK
00516 return S_IFSOCK;
00517 #endif
00518 case 'p': return S_IFIFO;
00519 case 'm': case 'n':
00520 case '-': case '?': return S_IFREG;
00521 default: return -1;
00522 }
00523 }
00524
00525 static int vfs_parse_filemode (const char *p)
00526
00527 {
00528 int res = 0;
00529 switch (*(p++)) {
00530 case 'r': res |= 0400; break;
00531 case '-': break;
00532 default: return -1;
00533 }
00534 switch (*(p++)) {
00535 case 'w': res |= 0200; break;
00536 case '-': break;
00537 default: return -1;
00538 }
00539 switch (*(p++)) {
00540 case 'x': res |= 0100; break;
00541 case 's': res |= 0100 | S_ISUID; break;
00542 case 'S': res |= S_ISUID; break;
00543 case '-': break;
00544 default: return -1;
00545 }
00546 switch (*(p++)) {
00547 case 'r': res |= 0040; break;
00548 case '-': break;
00549 default: return -1;
00550 }
00551 switch (*(p++)) {
00552 case 'w': res |= 0020; break;
00553 case '-': break;
00554 default: return -1;
00555 }
00556 switch (*(p++)) {
00557 case 'x': res |= 0010; break;
00558 case 's': res |= 0010 | S_ISGID; break;
00559 case 'l':
00560 case 'S': res |= S_ISGID; break;
00561 case '-': break;
00562 default: return -1;
00563 }
00564 switch (*(p++)) {
00565 case 'r': res |= 0004; break;
00566 case '-': break;
00567 default: return -1;
00568 }
00569 switch (*(p++)) {
00570 case 'w': res |= 0002; break;
00571 case '-': break;
00572 default: return -1;
00573 }
00574 switch (*(p++)) {
00575 case 'x': res |= 0001; break;
00576 case 't': res |= 0001 | S_ISVTX; break;
00577 case 'T': res |= S_ISVTX; break;
00578 case '-': break;
00579 default: return -1;
00580 }
00581 return res;
00582 }
00583
00584
00585 static int vfs_parse_filedate(int idx, time_t *t)
00586
00587 {
00588
00589 char *p;
00590 struct tm tim;
00591 int d[3];
00592 int got_year = 0;
00593
00594
00595 tim.tm_year = current_year;
00596 tim.tm_mon = current_mon;
00597 tim.tm_mday = current_mday;
00598 tim.tm_hour = 0;
00599 tim.tm_min = 0;
00600 tim.tm_sec = 0;
00601 tim.tm_isdst = -1;
00602
00603 p = columns [idx++];
00604
00605
00606 if(is_week(p, &tim))
00607 p = columns [idx++];
00608
00609
00610 if(is_month(p, &tim)){
00611
00612 if (is_num (idx))
00613 tim.tm_mday = (int)atol (columns [idx++]);
00614 else
00615 return 0;
00616
00617 } else {
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 if (is_dos_date(p)){
00631
00632 p[2] = p[5] = '-';
00633
00634
00635 memset(d, 0, sizeof(d));
00636 if (sscanf(p, "%2d-%2d-%2d", &d[0], &d[1], &d[2]) == 3){
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 d[0]--;
00647
00648 if(d[2] < 70)
00649 d[2] += 100;
00650
00651 tim.tm_mon = d[0];
00652 tim.tm_mday = d[1];
00653 tim.tm_year = d[2];
00654 got_year = 1;
00655 } else
00656 return 0;
00657 } else
00658 return 0;
00659 }
00660
00661
00662
00663 if (is_num (idx)) {
00664 if(is_time(columns[idx], &tim) || (got_year = is_year(columns[idx], &tim))) {
00665 idx++;
00666
00667
00668 if(is_num (idx) &&
00669 ((got_year = is_year(columns[idx], &tim)) || is_time(columns[idx], &tim)))
00670 idx++;
00671 }
00672 }
00673 else
00674 return 0;
00675
00676
00677
00678
00679
00680
00681
00682 if (!got_year &&
00683 current_mon < 6 && current_mon < tim.tm_mon &&
00684 tim.tm_mon - current_mon >= 6)
00685
00686 tim.tm_year--;
00687
00688 if ((*t = mktime(&tim)) < 0)
00689 *t = 0;
00690 return idx;
00691 }
00692
00693
00694
00695 static int
00696 vfs_parse_ls_lga (char * p, struct stat * st,
00697 const char ** filename,
00698 const char ** linkname)
00699
00700 {
00701 int idx, idx2, num_cols;
00702 int i;
00703 char *p_copy;
00704
00705 if (strncmp (p, "total", 5) == 0)
00706 return 0;
00707
00708 p_copy = g_strdup(p);
00709
00710
00711
00712 if ((i = vfs_parse_filetype(*(p++))) == -1)
00713 goto error;
00714
00715 st->st_mode = i;
00716 if (*p == ' ')
00717 p++;
00718 if (*p == '['){
00719 if (strlen (p) <= 8 || p [8] != ']')
00720 goto error;
00721
00722
00723 if (S_ISDIR (st->st_mode))
00724 st->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH);
00725 else
00726 st->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
00727 p += 9;
00728
00729 } else {
00730 if ((i = vfs_parse_filemode(p)) == -1)
00731 goto error;
00732 st->st_mode |= i;
00733 p += 9;
00734
00735
00736 if (*p == '+')
00737 p++;
00738 }
00739
00740 g_free(p_copy);
00741 p_copy = g_strdup(p);
00742 num_cols = vfs_split_text (p);
00743
00744 st->st_nlink = atol (columns [0]);
00745 if (st->st_nlink < 0)
00746 goto error;
00747
00748 if (!is_num (1))
00749 #ifdef HACK
00750 st->st_uid = finduid (columns [1]);
00751 #else
00752 (void) unameToUid (columns [1], &st->st_uid);
00753 #endif
00754 else
00755 st->st_uid = (uid_t) atol (columns [1]);
00756
00757
00758 for (idx = 3; idx <= 5; idx++)
00759 if (is_month(columns [idx], NULL) || is_week(columns [idx], NULL) || is_dos_date(columns[idx]))
00760 break;
00761
00762 if (idx == 6 || (idx == 5 && !S_ISCHR (st->st_mode) && !S_ISBLK (st->st_mode)))
00763 goto error;
00764
00765
00766 if (idx == 3 || (idx == 4 && (S_ISCHR(st->st_mode) || S_ISBLK (st->st_mode))))
00767 idx2 = 2;
00768 else {
00769
00770 if (is_num (2))
00771 st->st_gid = (gid_t) atol (columns [2]);
00772 else
00773 #ifdef HACK
00774 st->st_gid = findgid (columns [2]);
00775 #else
00776 (void) gnameToGid (columns [1], &st->st_gid);
00777 #endif
00778 idx2 = 3;
00779 }
00780
00781
00782 if (S_ISCHR (st->st_mode) || S_ISBLK (st->st_mode)){
00783 unsigned maj, min;
00784
00785 if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
00786 goto error;
00787
00788 if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
00789 goto error;
00790
00791 #ifdef HAVE_ST_RDEV
00792 st->st_rdev = ((maj & 0x000000ffU) << 8) | (min & 0x000000ffU);
00793 #endif
00794 st->st_size = 0;
00795
00796 } else {
00797
00798 if (!is_num (idx2))
00799 goto error;
00800
00801 st->st_size = (size_t) atol (columns [idx2]);
00802 #ifdef HAVE_ST_RDEV
00803 st->st_rdev = 0;
00804 #endif
00805 }
00806
00807 idx = vfs_parse_filedate(idx, &st->st_mtime);
00808 if (!idx)
00809 goto error;
00810
00811 st->st_atime = st->st_ctime = st->st_mtime;
00812 st->st_dev = 0;
00813 st->st_ino = 0;
00814 #ifdef HAVE_ST_BLKSIZE
00815 st->st_blksize = 512;
00816 #endif
00817 #ifdef HAVE_ST_BLOCKS
00818 st->st_blocks = (st->st_size + 511) / 512;
00819 #endif
00820
00821 for (i = idx + 1, idx2 = 0; i < num_cols; i++ )
00822 if (strcmp (columns [i], "->") == 0){
00823 idx2 = i;
00824 break;
00825 }
00826
00827 if (((S_ISLNK (st->st_mode) ||
00828 (num_cols == idx + 3 && st->st_nlink > 1)))
00829 && idx2){
00830 int tlen;
00831 char *t;
00832
00833 if (filename){
00834 #ifdef HACK
00835 t = g_strndup (p_copy + column_ptr [idx], column_ptr [idx2] - column_ptr [idx] - 1);
00836 #else
00837 int nb = column_ptr [idx2] - column_ptr [idx] - 1;
00838 t = xmalloc(nb+1);
00839 strncpy(t, p_copy + column_ptr [idx], nb);
00840 #endif
00841 *filename = t;
00842 }
00843 if (linkname){
00844 t = g_strdup (p_copy + column_ptr [idx2+1]);
00845 tlen = strlen (t);
00846 if (t [tlen-1] == '\r' || t [tlen-1] == '\n')
00847 t [tlen-1] = 0;
00848 if (t [tlen-2] == '\r' || t [tlen-2] == '\n')
00849 t [tlen-2] = 0;
00850
00851 *linkname = t;
00852 }
00853 } else {
00854
00855
00856
00857 if (filename){
00858
00859
00860
00861 int tlen;
00862 char *t;
00863
00864 t = g_strdup (p_copy + column_ptr [idx]); idx++;
00865 tlen = strlen (t);
00866
00867 if (t [tlen-1] == '\r' || t [tlen-1] == '\n')
00868 t [tlen-1] = 0;
00869 if (t [tlen-2] == '\r' || t [tlen-2] == '\n')
00870 t [tlen-2] = 0;
00871
00872 *filename = t;
00873 }
00874 if (linkname)
00875 *linkname = NULL;
00876 }
00877 g_free (p_copy);
00878 return 1;
00879
00880 error:
00881 #ifdef HACK
00882 {
00883 static int errorcount = 0;
00884
00885 if (++errorcount < 5) {
00886 message_1s (1, "Could not parse:", p_copy);
00887 } else if (errorcount == 5)
00888 message_1s (1, "More parsing errors will be ignored.", "(sorry)" );
00889 }
00890 #endif
00891
00892
00893 if (p_copy != p)
00894
00895 g_free (p_copy);
00896 return 0;
00897 }
00898
00899
00900 typedef enum {
00901 DO_FTP_STAT = 1,
00902 DO_FTP_LSTAT = 2,
00903 DO_FTP_READLINK = 3,
00904 DO_FTP_ACCESS = 4,
00905 DO_FTP_GLOB = 5
00906 } ftpSysCall_t;
00907
00910
00911 static size_t ftpBufAlloced = 0;
00912
00915
00916 static char * ftpBuf = NULL;
00917
00918 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00919
00920
00921 static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall,
00922 struct stat * st,
00923 char * rlbuf, size_t rlbufsiz)
00924
00925
00926
00927
00928 {
00929 FD_t fd;
00930 const char * path;
00931 int bufLength, moretodo;
00932 const char *n, *ne, *o, *oe;
00933 char * s;
00934 char * se;
00935 const char * urldn;
00936 char * bn = NULL;
00937 int nbn = 0;
00938 urlinfo u;
00939 int rc;
00940
00941 n = ne = o = oe = NULL;
00942 (void) urlPath(url, &path);
00943 if (*path == '\0')
00944 return -2;
00945
00946 switch (ftpSysCall) {
00947 case DO_FTP_GLOB:
00948 fd = ftpOpen(url, 0, 0, &u);
00949 if (fd == NULL || u == NULL)
00950 return -1;
00951
00952 u->openError = ftpReq(fd, "LIST", path);
00953 break;
00954 default:
00955 urldn = alloca_strdup(url);
00956
00957 if ((bn = strrchr(urldn, '/')) == NULL)
00958 return -2;
00959 else if (bn == path)
00960 bn = ".";
00961 else
00962 *bn++ = '\0';
00963
00964 nbn = strlen(bn);
00965
00966 rc = ftpChdir(urldn);
00967 if (rc < 0)
00968 return rc;
00969
00970 fd = ftpOpen(url, 0, 0, &u);
00971 if (fd == NULL || u == NULL)
00972 return -1;
00973
00974
00975 u->openError = ftpReq(fd, "NLST", "-la");
00976
00977 if (bn == NULL || nbn <= 0) {
00978 rc = -2;
00979 goto exit;
00980 }
00981 break;
00982 }
00983
00984 if (u->openError < 0) {
00985 fd = fdLink(fd, "error data (ftpStat)");
00986 rc = -2;
00987 goto exit;
00988 }
00989
00990 if (ftpBufAlloced == 0 || ftpBuf == NULL) {
00991 ftpBufAlloced = _url_iobuf_size;
00992 ftpBuf = xcalloc(ftpBufAlloced, sizeof(ftpBuf[0]));
00993 }
00994 *ftpBuf = '\0';
00995
00996 bufLength = 0;
00997 moretodo = 1;
00998
00999 do {
01000
01001
01002 if ((ftpBufAlloced - bufLength) < (1024+80)) {
01003 ftpBufAlloced <<= 2;
01004 assert(ftpBufAlloced < (8*1024*1024));
01005 ftpBuf = xrealloc(ftpBuf, ftpBufAlloced);
01006 }
01007 s = se = ftpBuf + bufLength;
01008 *se = '\0';
01009
01010 rc = fdFgets(fd, se, (ftpBufAlloced - bufLength));
01011 if (rc <= 0) {
01012 moretodo = 0;
01013 break;
01014 }
01015 if (ftpSysCall == DO_FTP_GLOB) {
01016 bufLength += strlen(se);
01017 continue;
01018 }
01019
01020 for (s = se; *s != '\0'; s = se) {
01021 int bingo;
01022
01023 while (*se && *se != '\n') se++;
01024 if (se > s && se[-1] == '\r') se[-1] = '\0';
01025 if (*se == '\0')
01026 break;
01027 *se++ = '\0';
01028
01029 if (!strncmp(s, "total ", sizeof("total ")-1))
01030 continue;
01031
01032 o = NULL;
01033 for (bingo = 0, n = se; n >= s; n--) {
01034 switch (*n) {
01035 case '\0':
01036 oe = ne = n;
01037 break;
01038 case ' ':
01039 if (o || !(n[-3] == ' ' && n[-2] == '-' && n[-1] == '>')) {
01040 while (*(++n) == ' ')
01041 {};
01042 bingo++;
01043 break;
01044 }
01045 for (o = n + 1; *o == ' '; o++)
01046 {};
01047 n -= 3;
01048 ne = n;
01049 break;
01050 default:
01051 break;
01052 }
01053 if (bingo)
01054 break;
01055 }
01056
01057 if (nbn != (ne - n))
01058 continue;
01059 if (strncmp(n, bn, nbn))
01060 continue;
01061
01062 moretodo = 0;
01063 break;
01064 }
01065
01066 if (moretodo && se > s) {
01067 bufLength = se - s - 1;
01068 if (s != ftpBuf)
01069 memmove(ftpBuf, s, bufLength);
01070 } else {
01071 bufLength = 0;
01072 }
01073 } while (moretodo);
01074
01075 switch (ftpSysCall) {
01076 case DO_FTP_STAT:
01077 if (o && oe) {
01078
01079 }
01080
01081 case DO_FTP_LSTAT:
01082 if (st == NULL || !(n && ne)) {
01083 rc = -1;
01084 } else {
01085 rc = ((vfs_parse_ls_lga(s, st, NULL, NULL) > 0) ? 0 : -1);
01086 }
01087 break;
01088 case DO_FTP_READLINK:
01089 if (rlbuf == NULL || !(o && oe)) {
01090 rc = -1;
01091 } else {
01092 rc = oe - o;
01093 if (rc > rlbufsiz)
01094 rc = rlbufsiz;
01095 memcpy(rlbuf, o, rc);
01096 if (rc < rlbufsiz)
01097 rlbuf[rc] = '\0';
01098 }
01099 break;
01100 case DO_FTP_ACCESS:
01101 rc = 0;
01102 break;
01103 case DO_FTP_GLOB:
01104 rc = 0;
01105 break;
01106 }
01107
01108 exit:
01109 (void) ufdClose(fd);
01110 return rc;
01111 }
01112
01113
01114 static const char * statstr(const struct stat * st,
01115 char * buf)
01116
01117 {
01118 sprintf(buf,
01119 "*** dev %x ino %x mode %0o nlink %d uid %d gid %d rdev %x size %x\n",
01120 (unsigned int)st->st_dev,
01121 (unsigned int)st->st_ino,
01122 (unsigned int)st->st_mode,
01123 (unsigned int)st->st_nlink,
01124 (unsigned int)st->st_uid,
01125 (unsigned int)st->st_gid,
01126 (unsigned int)st->st_rdev,
01127 (unsigned int)st->st_size);
01128 return buf;
01129 }
01130
01131
01132 static int ftp_st_ino = 0xdead0000;
01133
01134
01135 static int ftpStat(const char * path, struct stat *st)
01136
01137
01138 {
01139 char buf[1024];
01140 int rc;
01141 rc = ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
01142
01143 if (st->st_ino == 0)
01144 st->st_ino = ftp_st_ino++;
01145 if (_ftp_debug)
01146 fprintf(stderr, "*** ftpStat(%s) rc %d\n%s", path, rc, statstr(st, buf));
01147 return rc;
01148 }
01149
01150
01151 static int ftpLstat(const char * path, struct stat *st)
01152
01153
01154 {
01155 char buf[1024];
01156 int rc;
01157 rc = ftpNLST(path, DO_FTP_LSTAT, st, NULL, 0);
01158
01159 if (st->st_ino == 0)
01160 st->st_ino = ftp_st_ino++;
01161 if (_ftp_debug)
01162 fprintf(stderr, "*** ftpLstat(%s) rc %d\n%s\n", path, rc, statstr(st, buf));
01163 return rc;
01164 }
01165
01166 static int ftpReadlink(const char * path, char * buf, size_t bufsiz)
01167
01168
01169 {
01170 int rc;
01171 rc = ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
01172 if (_ftp_debug)
01173 fprintf(stderr, "*** ftpReadlink(%s) rc %d\n", path, rc);
01174 return rc;
01175 }
01176
01177
01178
01179 static DIR * ftpOpendir(const char * path)
01180
01181
01182 {
01183 AVDIR avdir;
01184 struct dirent * dp;
01185 size_t nb;
01186 const char * s, * sb, * se;
01187 const char ** av;
01188 unsigned char * dt;
01189 char * t;
01190 int ac;
01191 int c;
01192 int rc;
01193
01194 if (_ftp_debug)
01195 fprintf(stderr, "*** ftpOpendir(%s)\n", path);
01196 rc = ftpNLST(path, DO_FTP_GLOB, NULL, NULL, 0);
01197 if (rc)
01198 return NULL;
01199
01200
01201
01202
01203
01204 nb = sizeof(".") + sizeof("..");
01205 ac = 2;
01206 sb = NULL;
01207 s = se = ftpBuf;
01208 while ((c = *se) != '\0') {
01209 se++;
01210 switch (c) {
01211 case '/':
01212 sb = se;
01213 break;
01214 case '\r':
01215 if (sb == NULL) {
01216 for (sb = se; sb > s && sb[-1] != ' '; sb--)
01217 {};
01218 }
01219 ac++;
01220 nb += (se - sb);
01221
01222 if (*se == '\n') se++;
01223 sb = NULL;
01224 s = se;
01225 break;
01226 default:
01227 break;
01228 }
01229 }
01230
01231 nb += sizeof(*avdir) + sizeof(*dp) + ((ac + 1) * sizeof(*av)) + (ac + 1);
01232 avdir = xcalloc(1, nb);
01233
01234 dp = (struct dirent *) (avdir + 1);
01235 av = (const char **) (dp + 1);
01236 dt = (char *) (av + (ac + 1));
01237 t = (char *) (dt + ac + 1);
01238
01239
01240 avdir->fd = avmagicdir;
01241
01242 avdir->data = (char *) dp;
01243
01244 avdir->allocation = nb;
01245 avdir->size = ac;
01246 avdir->offset = -1;
01247 avdir->filepos = 0;
01248
01249 #if defined(HAVE_PTHREAD_H)
01250
01251 (void) pthread_mutex_init(&avdir->lock, NULL);
01252
01253 #endif
01254
01255 ac = 0;
01256
01257 dt[ac] = DT_DIR; av[ac++] = t; t = stpcpy(t, "."); t++;
01258 dt[ac] = DT_DIR; av[ac++] = t; t = stpcpy(t, ".."); t++;
01259
01260 sb = NULL;
01261 s = se = ftpBuf;
01262 while ((c = *se) != '\0') {
01263 se++;
01264 switch (c) {
01265 case '/':
01266 sb = se;
01267 break;
01268 case '\r':
01269
01270 av[ac] = t;
01271
01272 if (sb == NULL) {
01273
01274 switch(*s) {
01275 case 'p':
01276 dt[ac] = DT_FIFO;
01277 break;
01278 case 'c':
01279 dt[ac] = DT_CHR;
01280 break;
01281 case 'd':
01282 dt[ac] = DT_DIR;
01283 break;
01284 case 'b':
01285 dt[ac] = DT_BLK;
01286 break;
01287 case '-':
01288 dt[ac] = DT_REG;
01289 break;
01290 case 'l':
01291 dt[ac] = DT_LNK;
01292 break;
01293 case 's':
01294 dt[ac] = DT_SOCK;
01295 break;
01296 default:
01297 dt[ac] = DT_UNKNOWN;
01298 break;
01299 }
01300
01301 for (sb = se; sb > s && sb[-1] != ' '; sb--)
01302 {};
01303 }
01304 ac++;
01305 t = stpncpy(t, sb, (se - sb));
01306 t[-1] = '\0';
01307 if (*se == '\n') se++;
01308 sb = NULL;
01309 s = se;
01310 break;
01311 default:
01312 break;
01313 }
01314 }
01315 av[ac] = NULL;
01316
01317
01318 return (DIR *) avdir;
01319
01320 }
01321
01322
01323
01324 static char * ftpRealpath(const char * path, char * resolved_path)
01325
01326 {
01327 assert(resolved_path == NULL);
01328
01329 return xstrdup(path);
01330 }
01331
01332 int Stat(const char * path, struct stat * st)
01333 {
01334 const char * lpath;
01335 int ut = urlPath(path, &lpath);
01336
01337 if (_rpmio_debug)
01338 fprintf(stderr, "*** Stat(%s,%p)\n", path, st);
01339 switch (ut) {
01340 case URL_IS_FTP:
01341 return ftpStat(path, st);
01342 break;
01343 case URL_IS_PATH:
01344 path = lpath;
01345
01346 case URL_IS_UNKNOWN:
01347 break;
01348 case URL_IS_DASH:
01349 case URL_IS_HKP:
01350 default:
01351 errno = EINVAL;
01352 return -2;
01353 break;
01354 }
01355 return stat(path, st);
01356 }
01357
01358 int Lstat(const char * path, struct stat * st)
01359 {
01360 const char * lpath;
01361 int ut = urlPath(path, &lpath);
01362
01363 if (_rpmio_debug)
01364 fprintf(stderr, "*** Lstat(%s,%p)\n", path, st);
01365 switch (ut) {
01366 case URL_IS_FTP:
01367 return ftpLstat(path, st);
01368 break;
01369 case URL_IS_PATH:
01370 path = lpath;
01371
01372 case URL_IS_UNKNOWN:
01373 break;
01374 case URL_IS_DASH:
01375 case URL_IS_HKP:
01376 default:
01377 errno = EINVAL;
01378 return -2;
01379 break;
01380 }
01381 return lstat(path, st);
01382 }
01383
01384 int Chown(const char * path, uid_t owner, gid_t group)
01385 {
01386 const char * lpath;
01387 int ut = urlPath(path, &lpath);
01388
01389 if (_rpmio_debug)
01390 fprintf(stderr, "*** Chown(%s,%d,%d)\n", path, (int)owner, (int)group);
01391 switch (ut) {
01392 case URL_IS_PATH:
01393 path = lpath;
01394
01395 case URL_IS_UNKNOWN:
01396 break;
01397 case URL_IS_DASH:
01398 case URL_IS_HKP:
01399 case URL_IS_FTP:
01400 case URL_IS_HTTPS:
01401 case URL_IS_HTTP:
01402 default:
01403 errno = EINVAL;
01404 return -2;
01405 break;
01406 }
01407 return chown(path, owner, group);
01408 }
01409
01410 int Lchown(const char * path, uid_t owner, gid_t group)
01411 {
01412 const char * lpath;
01413 int ut = urlPath(path, &lpath);
01414
01415 if (_rpmio_debug)
01416 fprintf(stderr, "*** Lchown(%s,%d,%d)\n", path, (int)owner, (int)group);
01417 switch (ut) {
01418 case URL_IS_PATH:
01419 path = lpath;
01420
01421 case URL_IS_UNKNOWN:
01422 break;
01423 case URL_IS_DASH:
01424 case URL_IS_HKP:
01425 case URL_IS_FTP:
01426 case URL_IS_HTTPS:
01427 case URL_IS_HTTP:
01428 default:
01429 errno = EINVAL;
01430 return -2;
01431 break;
01432 }
01433 return lchown(path, owner, group);
01434 }
01435
01436 int Chmod(const char * path, mode_t mode)
01437 {
01438 const char * lpath;
01439 int ut = urlPath(path, &lpath);
01440
01441 if (_rpmio_debug)
01442 fprintf(stderr, "*** Chmod(%s,%0o)\n", path, (int)mode);
01443 switch (ut) {
01444 case URL_IS_PATH:
01445 path = lpath;
01446
01447 case URL_IS_UNKNOWN:
01448 break;
01449 case URL_IS_DASH:
01450 case URL_IS_HKP:
01451 case URL_IS_FTP:
01452 case URL_IS_HTTPS:
01453 case URL_IS_HTTP:
01454 default:
01455 errno = EINVAL;
01456 return -2;
01457 break;
01458 }
01459 return chmod(path, mode);
01460 }
01461
01462 int Mkfifo(const char * path, mode_t mode)
01463 {
01464 const char * lpath;
01465 int ut = urlPath(path, &lpath);
01466
01467 if (_rpmio_debug)
01468 fprintf(stderr, "*** Mkfifo(%s,%0o)\n", path, (int)mode);
01469 switch (ut) {
01470 case URL_IS_PATH:
01471 path = lpath;
01472
01473 case URL_IS_UNKNOWN:
01474 break;
01475 case URL_IS_DASH:
01476 case URL_IS_HKP:
01477 case URL_IS_FTP:
01478 case URL_IS_HTTPS:
01479 case URL_IS_HTTP:
01480 default:
01481 errno = EINVAL;
01482 return -2;
01483 break;
01484 }
01485 return mkfifo(path, mode);
01486 }
01487
01488 int Mknod(const char * path, mode_t mode, dev_t dev)
01489 {
01490 const char * lpath;
01491 int ut = urlPath(path, &lpath);
01492
01493 if (_rpmio_debug)
01494 fprintf(stderr, "*** Mknod(%s,%0o, 0x%x)\n", path, (int)mode, (int)dev);
01495 switch (ut) {
01496 case URL_IS_PATH:
01497 path = lpath;
01498
01499 case URL_IS_UNKNOWN:
01500 break;
01501 case URL_IS_DASH:
01502 case URL_IS_HKP:
01503 case URL_IS_FTP:
01504 case URL_IS_HTTPS:
01505 case URL_IS_HTTP:
01506 default:
01507 errno = EINVAL;
01508 return -2;
01509 break;
01510 }
01511
01512 return mknod(path, mode, dev);
01513
01514 }
01515
01516 int Utime(const char * path, const struct utimbuf *buf)
01517 {
01518 const char * lpath;
01519 int ut = urlPath(path, &lpath);
01520
01521 if (_rpmio_debug)
01522 fprintf(stderr, "*** Utime(%s,%p)\n", path, buf);
01523 switch (ut) {
01524 case URL_IS_PATH:
01525 path = lpath;
01526
01527 case URL_IS_UNKNOWN:
01528 break;
01529 case URL_IS_DASH:
01530 case URL_IS_HKP:
01531 case URL_IS_FTP:
01532 case URL_IS_HTTPS:
01533 case URL_IS_HTTP:
01534 default:
01535 errno = EINVAL;
01536 return -2;
01537 break;
01538 }
01539 return utime(path, buf);
01540 }
01541
01542
01543 int Utimes(const char * path, const struct timeval times[2])
01544 {
01545 const char * lpath;
01546 int ut = urlPath(path, &lpath);
01547
01548 if (_rpmio_debug)
01549 fprintf(stderr, "*** Utimes(%s,%p)\n", path, times);
01550 switch (ut) {
01551 case URL_IS_PATH:
01552 path = lpath;
01553
01554 case URL_IS_UNKNOWN:
01555 break;
01556 case URL_IS_DASH:
01557 case URL_IS_HKP:
01558 case URL_IS_FTP:
01559 case URL_IS_HTTPS:
01560 case URL_IS_HTTP:
01561 default:
01562 errno = EINVAL;
01563 return -2;
01564 break;
01565 }
01566 return utimes(path, times);
01567 }
01568
01569
01570 int Symlink(const char * oldpath, const char * newpath)
01571 {
01572 const char * opath;
01573 int out = urlPath(oldpath, &opath);
01574 const char * npath;
01575 int nut = urlPath(newpath, &npath);
01576
01577 nut = 0;
01578 if (_rpmio_debug)
01579 fprintf(stderr, "*** Symlink(%s,%s)\n", oldpath, newpath);
01580 switch (out) {
01581 case URL_IS_PATH:
01582 oldpath = opath;
01583 newpath = npath;
01584
01585 case URL_IS_UNKNOWN:
01586 break;
01587 case URL_IS_DASH:
01588 case URL_IS_HKP:
01589 case URL_IS_FTP:
01590 case URL_IS_HTTPS:
01591 case URL_IS_HTTP:
01592 default:
01593 errno = EINVAL;
01594 return -2;
01595 break;
01596 }
01597 return symlink(oldpath, newpath);
01598 }
01599
01600 int Readlink(const char * path, char * buf, size_t bufsiz)
01601 {
01602 const char * lpath;
01603 int ut = urlPath(path, &lpath);
01604
01605 if (_rpmio_debug)
01606 fprintf(stderr, "*** Readlink(%s,%p[%u])\n", path, buf, (unsigned)bufsiz);
01607 switch (ut) {
01608 case URL_IS_FTP:
01609 return ftpReadlink(path, buf, bufsiz);
01610 break;
01611 case URL_IS_PATH:
01612 path = lpath;
01613
01614 case URL_IS_UNKNOWN:
01615 break;
01616 case URL_IS_DASH:
01617 case URL_IS_HKP:
01618 default:
01619 errno = EINVAL;
01620 return -2;
01621 break;
01622 }
01623
01624 return readlink(path, buf, bufsiz);
01625
01626 }
01627
01628 int Access(const char * path, int amode)
01629 {
01630 const char * lpath;
01631 int ut = urlPath(path, &lpath);
01632
01633 if (_rpmio_debug)
01634 fprintf(stderr, "*** Access(%s,%d)\n", path, amode);
01635 switch (ut) {
01636 case URL_IS_PATH:
01637 path = lpath;
01638
01639 case URL_IS_UNKNOWN:
01640 break;
01641 case URL_IS_DASH:
01642 case URL_IS_HKP:
01643 case URL_IS_HTTPS:
01644 case URL_IS_HTTP:
01645 case URL_IS_FTP:
01646 default:
01647 errno = EINVAL;
01648 return -2;
01649 break;
01650 }
01651 return access(path, amode);
01652 }
01653
01654
01655
01656
01657
01658
01659 int Glob_pattern_p (const char * pattern, int quote)
01660 {
01661 const char *p;
01662 int ut = urlPath(pattern, &p);
01663 int open = 0;
01664 char c;
01665
01666 while ((c = *p++) != '\0')
01667 switch (c) {
01668 case '?':
01669
01670 if (ut == URL_IS_HTTPS || ut == URL_IS_HTTP || ut == URL_IS_HKP)
01671 continue;
01672
01673 case '*':
01674 return (1);
01675 case '\\':
01676 if (quote && *p != '\0')
01677 p++;
01678 continue;
01679
01680 case '[':
01681 open = 1;
01682 continue;
01683 case ']':
01684 if (open)
01685 return (1);
01686 continue;
01687
01688 case '+':
01689 case '@':
01690 case '!':
01691 if (*p == '(')
01692 return (1);
01693 continue;
01694 }
01695
01696 return (0);
01697 }
01698
01699 int Glob_error(const char * epath, int eerrno)
01700 {
01701 return 1;
01702 }
01703
01704 int Glob(const char *pattern, int flags,
01705 int errfunc(const char * epath, int eerrno), glob_t *pglob)
01706 {
01707 const char * lpath;
01708 int ut = urlPath(pattern, &lpath);
01709
01710
01711 if (_rpmio_debug)
01712 fprintf(stderr, "*** Glob(%s,0x%x,%p,%p)\n", pattern, (unsigned)flags, (void *)errfunc, pglob);
01713
01714 switch (ut) {
01715 case URL_IS_HTTPS:
01716 case URL_IS_HTTP:
01717 case URL_IS_FTP:
01718
01719 pglob->gl_closedir = Closedir;
01720 pglob->gl_readdir = Readdir;
01721 pglob->gl_opendir = Opendir;
01722 pglob->gl_lstat = Lstat;
01723 pglob->gl_stat = Stat;
01724
01725 flags |= GLOB_ALTDIRFUNC;
01726 flags &= ~GLOB_TILDE;
01727 break;
01728 case URL_IS_PATH:
01729 pattern = lpath;
01730
01731 case URL_IS_UNKNOWN:
01732 break;
01733 case URL_IS_DASH:
01734 case URL_IS_HKP:
01735 default:
01736 return -2;
01737 break;
01738 }
01739 return glob(pattern, flags, errfunc, pglob);
01740 }
01741
01742 void Globfree(glob_t *pglob)
01743 {
01744 if (_rpmio_debug)
01745 fprintf(stderr, "*** Globfree(%p)\n", pglob);
01746 globfree(pglob);
01747 }
01748
01749 DIR * Opendir(const char * path)
01750 {
01751 const char * lpath;
01752 int ut = urlPath(path, &lpath);
01753
01754 if (_rpmio_debug)
01755 fprintf(stderr, "*** Opendir(%s)\n", path);
01756 switch (ut) {
01757 case URL_IS_FTP:
01758 return ftpOpendir(path);
01759 break;
01760 case URL_IS_PATH:
01761 path = lpath;
01762
01763 case URL_IS_UNKNOWN:
01764 break;
01765 case URL_IS_DASH:
01766 case URL_IS_HKP:
01767 default:
01768 return NULL;
01769 break;
01770 }
01771
01772 return opendir(path);
01773
01774 }
01775
01776 struct dirent * Readdir(DIR * dir)
01777 {
01778 if (_rpmio_debug)
01779 fprintf(stderr, "*** Readdir(%p)\n", (void *)dir);
01780 if (dir == NULL)
01781 return NULL;
01782 if (ISAVMAGIC(dir))
01783 return avReaddir(dir);
01784 return readdir(dir);
01785 }
01786
01787 int Closedir(DIR * dir)
01788 {
01789 if (_rpmio_debug)
01790 fprintf(stderr, "*** Closedir(%p)\n", (void *)dir);
01791 if (dir == NULL)
01792 return 0;
01793 if (ISAVMAGIC(dir))
01794 return avClosedir(dir);
01795 return closedir(dir);
01796 }
01797
01798 char * Realpath(const char * path, char * resolved_path)
01799 {
01800 const char * lpath;
01801 int ut = urlPath(path, &lpath);
01802 char * rpath;
01803
01804 if (_rpmio_debug)
01805 fprintf(stderr, "*** Realpath(%s, %s)\n", path, (resolved_path ? resolved_path : "NULL"));
01806
01807
01808
01809 if (path == NULL || resolved_path != NULL)
01810 return realpath(path, resolved_path);
01811
01812
01813 switch (ut) {
01814 case URL_IS_FTP:
01815 return ftpRealpath(path, resolved_path);
01816 break;
01817 default:
01818 return xstrdup(path);
01819 break;
01820 case URL_IS_DASH:
01821
01822 #if defined(__linux__)
01823 lpath = "/dev/stdin";
01824 #else
01825 lpath = NULL;
01826 #endif
01827 break;
01828 case URL_IS_PATH:
01829 case URL_IS_UNKNOWN:
01830 path = lpath;
01831 break;
01832 }
01833
01834 if (lpath == NULL || *lpath == '/')
01835
01836 rpath = realpath(lpath, resolved_path);
01837
01838 else {
01839 char * t;
01840 #if defined(__GLIBC__)
01841 char * dn = NULL;
01842 #else
01843 char dn[PATH_MAX];
01844 dn[0] = '\0';
01845 #endif
01846
01847
01848
01849
01850
01851
01852 if ((t = realpath(".", dn)) != NULL) {
01853
01854 rpath = (char *) rpmGetPath(t, "/", lpath, NULL);
01855
01856 if (lpath[strlen(lpath)-1] == '/') {
01857 char * s = rpath;
01858 rpath = rpmExpand(s, "/", NULL);
01859 s = _free(s);
01860 }
01861
01862 } else
01863 rpath = NULL;
01864 #if defined(__GLIBC__)
01865 t = _free(t);
01866 #endif
01867 }
01868
01869 return rpath;
01870 }
01871
01872 off_t Lseek(int fdno, off_t offset, int whence)
01873 {
01874 if (_rpmio_debug)
01875 fprintf(stderr, "*** Lseek(%d,0x%lx,%d)\n", fdno, (long)offset, whence);
01876 return lseek(fdno, offset, whence);
01877 }