00001
00006 #include "system.h"
00007 #include <rpmio_internal.h>
00008 #include <popt.h>
00009 #include "ugid.h"
00010 #include "debug.h"
00011
00012
00013
00014
00015
00016 extern int _rpmio_debug;
00017
00018
00019
00020 static int ftpMkdir(const char * path, mode_t mode)
00021
00022
00023 {
00024 int rc;
00025 if ((rc = ftpCmd("MKD", path, NULL)) != 0)
00026 return rc;
00027 #if NOTYET
00028 { char buf[20];
00029 sprintf(buf, " 0%o", mode);
00030 (void) ftpCmd("SITE CHMOD", path, buf);
00031 }
00032 #endif
00033 return rc;
00034 }
00035
00036 static int ftpChdir(const char * path)
00037
00038
00039 {
00040 return ftpCmd("CWD", path, NULL);
00041 }
00042
00043 static int ftpRmdir(const char * path)
00044
00045
00046 {
00047 return ftpCmd("RMD", path, NULL);
00048 }
00049
00050 static int ftpRename(const char * oldpath, const char * newpath)
00051
00052
00053 {
00054 int rc;
00055 if ((rc = ftpCmd("RNFR", oldpath, NULL)) != 0)
00056 return rc;
00057 return ftpCmd("RNTO", newpath, NULL);
00058 }
00059
00060 static int ftpUnlink(const char * path)
00061
00062
00063 {
00064 return ftpCmd("DELE", path, NULL);
00065 }
00066
00067
00068
00069 int Mkdir (const char * path, mode_t mode)
00070 {
00071 const char * lpath;
00072 int ut = urlPath(path, &lpath);
00073
00074 switch (ut) {
00075 case URL_IS_FTP:
00076 return ftpMkdir(path, mode);
00077 break;
00078 case URL_IS_HTTP:
00079 case URL_IS_PATH:
00080 path = lpath;
00081
00082 case URL_IS_UNKNOWN:
00083 break;
00084 case URL_IS_DASH:
00085 default:
00086 return -2;
00087 break;
00088 }
00089 return mkdir(path, mode);
00090 }
00091
00092 int Chdir (const char * path)
00093 {
00094 const char * lpath;
00095 int ut = urlPath(path, &lpath);
00096
00097 switch (ut) {
00098 case URL_IS_FTP:
00099 return ftpChdir(path);
00100 break;
00101 case URL_IS_HTTP:
00102 case URL_IS_PATH:
00103 path = lpath;
00104
00105 case URL_IS_UNKNOWN:
00106 break;
00107 case URL_IS_DASH:
00108 default:
00109 return -2;
00110 break;
00111 }
00112 return chdir(path);
00113 }
00114
00115 int Rmdir (const char * path)
00116 {
00117 const char * lpath;
00118 int ut = urlPath(path, &lpath);
00119
00120 switch (ut) {
00121 case URL_IS_FTP:
00122 return ftpRmdir(path);
00123 break;
00124 case URL_IS_HTTP:
00125 case URL_IS_PATH:
00126 path = lpath;
00127
00128 case URL_IS_UNKNOWN:
00129 break;
00130 case URL_IS_DASH:
00131 default:
00132 return -2;
00133 break;
00134 }
00135 return rmdir(path);
00136 }
00137
00138
00139
00140 int Rename (const char * oldpath, const char * newpath)
00141 {
00142 const char *oe = NULL;
00143 const char *ne = NULL;
00144 int oldut, newut;
00145
00146
00147 if (!strcmp(oldpath, newpath)) return 0;
00148
00149 oldut = urlPath(oldpath, &oe);
00150 switch (oldut) {
00151 case URL_IS_FTP:
00152 case URL_IS_HTTP:
00153 case URL_IS_PATH:
00154 case URL_IS_UNKNOWN:
00155 break;
00156 case URL_IS_DASH:
00157 default:
00158 return -2;
00159 break;
00160 }
00161
00162 newut = urlPath(newpath, &ne);
00163 switch (newut) {
00164 case URL_IS_FTP:
00165 if (_rpmio_debug)
00166 fprintf(stderr, "*** rename old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
00167 if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
00168 !xstrncasecmp(oldpath, newpath, (oe - oldpath))))
00169 return -2;
00170 return ftpRename(oldpath, newpath);
00171 break;
00172 case URL_IS_HTTP:
00173 case URL_IS_PATH:
00174 oldpath = oe;
00175 newpath = ne;
00176 break;
00177 case URL_IS_UNKNOWN:
00178 break;
00179 case URL_IS_DASH:
00180 default:
00181 return -2;
00182 break;
00183 }
00184 return rename(oldpath, newpath);
00185 }
00186
00187 int Link (const char * oldpath, const char * newpath)
00188 {
00189 const char *oe = NULL;
00190 const char *ne = NULL;
00191 int oldut, newut;
00192
00193 oldut = urlPath(oldpath, &oe);
00194 switch (oldut) {
00195 case URL_IS_FTP:
00196 case URL_IS_HTTP:
00197 case URL_IS_PATH:
00198 case URL_IS_UNKNOWN:
00199 break;
00200 case URL_IS_DASH:
00201 default:
00202 return -2;
00203 break;
00204 }
00205
00206 newut = urlPath(newpath, &ne);
00207 switch (newut) {
00208 case URL_IS_HTTP:
00209 case URL_IS_FTP:
00210 case URL_IS_PATH:
00211 if (_rpmio_debug)
00212 fprintf(stderr, "*** link old %*s new %*s\n", (int)(oe - oldpath), oldpath, (int)(ne - newpath), newpath);
00213 if (!(oldut == newut && oe && ne && (oe - oldpath) == (ne - newpath) &&
00214 !xstrncasecmp(oldpath, newpath, (oe - oldpath))))
00215 return -2;
00216 oldpath = oe;
00217 newpath = ne;
00218 break;
00219 case URL_IS_UNKNOWN:
00220 break;
00221 case URL_IS_DASH:
00222 default:
00223 return -2;
00224 break;
00225 }
00226 return link(oldpath, newpath);
00227 }
00228
00229
00230
00231 int Unlink(const char * path) {
00232 const char * lpath;
00233 int ut = urlPath(path, &lpath);
00234
00235 switch (ut) {
00236 case URL_IS_FTP:
00237 return ftpUnlink(path);
00238 break;
00239 case URL_IS_HTTP:
00240 case URL_IS_PATH:
00241 path = lpath;
00242
00243 case URL_IS_UNKNOWN:
00244 break;
00245 case URL_IS_DASH:
00246 default:
00247 return -2;
00248 break;
00249 }
00250 return unlink(path);
00251 }
00252
00253
00254
00255 #define g_strdup xstrdup
00256 #define g_free free
00257
00258
00259
00260
00261
00262 static int current_mday;
00263
00264 static int current_mon;
00265
00266 static int current_year;
00267
00268
00269 #define MAXCOLS 30
00270
00271
00272 static char *columns [MAXCOLS];
00273
00274 static int column_ptr [MAXCOLS];
00275
00276 static int
00277 vfs_split_text (char *p)
00278
00279
00280 {
00281 char *original = p;
00282 int numcols;
00283
00284
00285 for (numcols = 0; *p && numcols < MAXCOLS; numcols++){
00286 while (*p == ' ' || *p == '\r' || *p == '\n'){
00287 *p = 0;
00288 p++;
00289 }
00290 columns [numcols] = p;
00291 column_ptr [numcols] = p - original;
00292 while (*p && *p != ' ' && *p != '\r' && *p != '\n')
00293 p++;
00294 }
00295 return numcols;
00296 }
00297
00298 static int
00299 is_num (int idx)
00300
00301 {
00302 if (!columns [idx] || columns [idx][0] < '0' || columns [idx][0] > '9')
00303 return 0;
00304 return 1;
00305 }
00306
00307 static int
00308 is_dos_date( const char *str)
00309
00310 {
00311 if (str != NULL && strlen(str) == 8 &&
00312 str[2] == str[5] && strchr("\\-/", (int)str[2]) != NULL)
00313 return 1;
00314 return 0;
00315 }
00316
00317 static int
00318 is_week ( const char * str, struct tm * tim)
00319
00320 {
00321 static const char * week = "SunMonTueWedThuFriSat";
00322 const char * pos;
00323
00324
00325 if (str != NULL && (pos=strstr(week, str)) != NULL) {
00326
00327 if (tim != NULL)
00328 tim->tm_wday = (pos - week)/3;
00329 return 1;
00330 }
00331 return 0;
00332 }
00333
00334 static int
00335 is_month ( const char * str, struct tm * tim)
00336
00337 {
00338 static const char * month = "JanFebMarAprMayJunJulAugSepOctNovDec";
00339 const char * pos;
00340
00341
00342 if (str != NULL && (pos = strstr(month, str)) != NULL) {
00343
00344 if (tim != NULL)
00345 tim->tm_mon = (pos - month)/3;
00346 return 1;
00347 }
00348 return 0;
00349 }
00350
00351 static int
00352 is_time ( const char * str, struct tm * tim)
00353
00354 {
00355 const char * p, * p2;
00356
00357 if (str != NULL && (p = strchr(str, ':')) && (p2 = strrchr(str, ':'))) {
00358 if (p != p2) {
00359 if (sscanf (str, "%2d:%2d:%2d", &tim->tm_hour, &tim->tm_min, &tim->tm_sec) != 3)
00360 return 0;
00361 } else {
00362 if (sscanf (str, "%2d:%2d", &tim->tm_hour, &tim->tm_min) != 2)
00363 return 0;
00364 }
00365 } else
00366 return 0;
00367
00368 return 1;
00369 }
00370
00371 static int is_year( const char * str, struct tm * tim)
00372
00373 {
00374 long year;
00375
00376 if (str == NULL)
00377 return 0;
00378
00379 if (strchr(str,':'))
00380 return 0;
00381
00382 if (strlen(str) != 4)
00383 return 0;
00384
00385 if (sscanf(str, "%ld", &year) != 1)
00386 return 0;
00387
00388 if (year < 1900 || year > 3000)
00389 return 0;
00390
00391 tim->tm_year = (int) (year - 1900);
00392
00393 return 1;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 static int
00403 vfs_parse_filetype (char c)
00404
00405 {
00406 switch (c) {
00407 case 'd': return S_IFDIR;
00408 case 'b': return S_IFBLK;
00409 case 'c': return S_IFCHR;
00410 case 'l': return S_IFLNK;
00411 case 's':
00412 #ifdef IS_IFSOCK
00413 return S_IFSOCK;
00414 #endif
00415 case 'p': return S_IFIFO;
00416 case 'm': case 'n':
00417 case '-': case '?': return S_IFREG;
00418 default: return -1;
00419 }
00420 }
00421
00422 static int vfs_parse_filemode (const char *p)
00423
00424 {
00425 int res = 0;
00426 switch (*(p++)) {
00427 case 'r': res |= 0400; break;
00428 case '-': break;
00429 default: return -1;
00430 }
00431 switch (*(p++)) {
00432 case 'w': res |= 0200; break;
00433 case '-': break;
00434 default: return -1;
00435 }
00436 switch (*(p++)) {
00437 case 'x': res |= 0100; break;
00438 case 's': res |= 0100 | S_ISUID; break;
00439 case 'S': res |= S_ISUID; break;
00440 case '-': break;
00441 default: return -1;
00442 }
00443 switch (*(p++)) {
00444 case 'r': res |= 0040; break;
00445 case '-': break;
00446 default: return -1;
00447 }
00448 switch (*(p++)) {
00449 case 'w': res |= 0020; break;
00450 case '-': break;
00451 default: return -1;
00452 }
00453 switch (*(p++)) {
00454 case 'x': res |= 0010; break;
00455 case 's': res |= 0010 | S_ISGID; break;
00456 case 'l':
00457 case 'S': res |= S_ISGID; break;
00458 case '-': break;
00459 default: return -1;
00460 }
00461 switch (*(p++)) {
00462 case 'r': res |= 0004; break;
00463 case '-': break;
00464 default: return -1;
00465 }
00466 switch (*(p++)) {
00467 case 'w': res |= 0002; break;
00468 case '-': break;
00469 default: return -1;
00470 }
00471 switch (*(p++)) {
00472 case 'x': res |= 0001; break;
00473 case 't': res |= 0001 | S_ISVTX; break;
00474 case 'T': res |= S_ISVTX; break;
00475 case '-': break;
00476 default: return -1;
00477 }
00478 return res;
00479 }
00480
00481 static int vfs_parse_filedate(int idx, time_t *t)
00482
00483 {
00484
00485 char *p;
00486 struct tm tim;
00487 int d[3];
00488 int got_year = 0;
00489
00490
00491 tim.tm_year = current_year;
00492 tim.tm_mon = current_mon;
00493 tim.tm_mday = current_mday;
00494 tim.tm_hour = 0;
00495 tim.tm_min = 0;
00496 tim.tm_sec = 0;
00497 tim.tm_isdst = -1;
00498
00499 p = columns [idx++];
00500
00501
00502 if(is_week(p, &tim))
00503 p = columns [idx++];
00504
00505
00506 if(is_month(p, &tim)){
00507
00508 if (is_num (idx))
00509 tim.tm_mday = (int)atol (columns [idx++]);
00510 else
00511 return 0;
00512
00513 } else {
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 if (is_dos_date(p)){
00527
00528 p[2] = p[5] = '-';
00529
00530
00531 memset(d, 0, sizeof(d));
00532 if (sscanf(p, "%2d-%2d-%2d", &d[0], &d[1], &d[2]) == 3){
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 d[0]--;
00543
00544 if(d[2] < 70)
00545 d[2] += 100;
00546
00547 tim.tm_mon = d[0];
00548 tim.tm_mday = d[1];
00549 tim.tm_year = d[2];
00550 got_year = 1;
00551 } else
00552 return 0;
00553 } else
00554 return 0;
00555 }
00556
00557
00558
00559 if (is_num (idx)) {
00560 if(is_time(columns[idx], &tim) || (got_year = is_year(columns[idx], &tim))) {
00561 idx++;
00562
00563
00564 if(is_num (idx) &&
00565 ((got_year = is_year(columns[idx], &tim)) || is_time(columns[idx], &tim)))
00566 idx++;
00567 }
00568 }
00569 else
00570 return 0;
00571
00572
00573
00574
00575
00576
00577
00578 if (!got_year &&
00579 current_mon < 6 && current_mon < tim.tm_mon &&
00580 tim.tm_mon - current_mon >= 6)
00581
00582 tim.tm_year--;
00583
00584 if ((*t = mktime(&tim)) < 0)
00585 *t = 0;
00586 return idx;
00587 }
00588
00589 static int
00590 vfs_parse_ls_lga (char * p, struct stat * st,
00591 const char ** filename,
00592 const char ** linkname)
00593
00594 {
00595 int idx, idx2, num_cols;
00596 int i;
00597 char *p_copy;
00598
00599 if (strncmp (p, "total", 5) == 0)
00600 return 0;
00601
00602 p_copy = g_strdup(p);
00603
00604
00605
00606 if ((i = vfs_parse_filetype(*(p++))) == -1)
00607 goto error;
00608
00609 st->st_mode = i;
00610 if (*p == ' ')
00611 p++;
00612 if (*p == '['){
00613 if (strlen (p) <= 8 || p [8] != ']')
00614 goto error;
00615
00616
00617 if (S_ISDIR (st->st_mode))
00618 st->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH);
00619 else
00620 st->st_mode |= (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
00621 p += 9;
00622
00623 } else {
00624 if ((i = vfs_parse_filemode(p)) == -1)
00625 goto error;
00626 st->st_mode |= i;
00627 p += 9;
00628
00629
00630 if (*p == '+')
00631 p++;
00632 }
00633
00634 g_free(p_copy);
00635 p_copy = g_strdup(p);
00636 num_cols = vfs_split_text (p);
00637
00638 st->st_nlink = atol (columns [0]);
00639 if (st->st_nlink < 0)
00640 goto error;
00641
00642 if (!is_num (1))
00643 #ifdef HACK
00644 st->st_uid = finduid (columns [1]);
00645 #else
00646 (void) unameToUid (columns [1], &st->st_uid);
00647 #endif
00648 else
00649 st->st_uid = (uid_t) atol (columns [1]);
00650
00651
00652 for (idx = 3; idx <= 5; idx++)
00653 if (is_month(columns [idx], NULL) || is_week(columns [idx], NULL) || is_dos_date(columns[idx]))
00654 break;
00655
00656 if (idx == 6 || (idx == 5 && !S_ISCHR (st->st_mode) && !S_ISBLK (st->st_mode)))
00657 goto error;
00658
00659
00660 if (idx == 3 || (idx == 4 && (S_ISCHR(st->st_mode) || S_ISBLK (st->st_mode))))
00661 idx2 = 2;
00662 else {
00663
00664 if (is_num (2))
00665 st->st_gid = (gid_t) atol (columns [2]);
00666 else
00667 #ifdef HACK
00668 st->st_gid = findgid (columns [2]);
00669 #else
00670 (void) gnameToGid (columns [1], &st->st_gid);
00671 #endif
00672 idx2 = 3;
00673 }
00674
00675
00676 if (S_ISCHR (st->st_mode) || S_ISBLK (st->st_mode)){
00677 int maj, min;
00678
00679 if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
00680 goto error;
00681
00682 if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
00683 goto error;
00684
00685 #ifdef HAVE_ST_RDEV
00686 st->st_rdev = ((maj & 0xff) << 8) | (min & 0xffff00ff);
00687 #endif
00688 st->st_size = 0;
00689
00690 } else {
00691
00692 if (!is_num (idx2))
00693 goto error;
00694
00695 st->st_size = (size_t) atol (columns [idx2]);
00696 #ifdef HAVE_ST_RDEV
00697 st->st_rdev = 0;
00698 #endif
00699 }
00700
00701 idx = vfs_parse_filedate(idx, &st->st_mtime);
00702 if (!idx)
00703 goto error;
00704
00705 st->st_atime = st->st_ctime = st->st_mtime;
00706 st->st_dev = 0;
00707 st->st_ino = 0;
00708 #ifdef HAVE_ST_BLKSIZE
00709 st->st_blksize = 512;
00710 #endif
00711 #ifdef HAVE_ST_BLOCKS
00712 st->st_blocks = (st->st_size + 511) / 512;
00713 #endif
00714
00715 for (i = idx + 1, idx2 = 0; i < num_cols; i++ )
00716 if (strcmp (columns [i], "->") == 0){
00717 idx2 = i;
00718 break;
00719 }
00720
00721 if (((S_ISLNK (st->st_mode) ||
00722 (num_cols == idx + 3 && st->st_nlink > 1)))
00723 && idx2){
00724 int tlen;
00725 char *t;
00726
00727 if (filename){
00728 #ifdef HACK
00729 t = g_strndup (p_copy + column_ptr [idx], column_ptr [idx2] - column_ptr [idx] - 1);
00730 #else
00731 int nb = column_ptr [idx2] - column_ptr [idx] - 1;
00732 t = xmalloc(nb+1);
00733 strncpy(t, p_copy + column_ptr [idx], nb);
00734 #endif
00735 *filename = t;
00736 }
00737 if (linkname){
00738 t = g_strdup (p_copy + column_ptr [idx2+1]);
00739 tlen = strlen (t);
00740 if (t [tlen-1] == '\r' || t [tlen-1] == '\n')
00741 t [tlen-1] = 0;
00742 if (t [tlen-2] == '\r' || t [tlen-2] == '\n')
00743 t [tlen-2] = 0;
00744
00745 *linkname = t;
00746 }
00747 } else {
00748
00749
00750
00751 if (filename){
00752
00753
00754
00755 int tlen;
00756 char *t;
00757
00758 t = g_strdup (p_copy + column_ptr [idx++]);
00759 tlen = strlen (t);
00760
00761 if (t [tlen-1] == '\r' || t [tlen-1] == '\n')
00762 t [tlen-1] = 0;
00763 if (t [tlen-2] == '\r' || t [tlen-2] == '\n')
00764 t [tlen-2] = 0;
00765
00766 *filename = t;
00767 }
00768 if (linkname)
00769 *linkname = NULL;
00770 }
00771 g_free (p_copy);
00772 return 1;
00773
00774 error:
00775 #ifdef HACK
00776 {
00777 static int errorcount = 0;
00778
00779 if (++errorcount < 5) {
00780 message_1s (1, "Could not parse:", p_copy);
00781 } else if (errorcount == 5)
00782 message_1s (1, "More parsing errors will be ignored.", "(sorry)" );
00783 }
00784 #endif
00785
00786
00787 if (p_copy != p)
00788
00789 g_free (p_copy);
00790 return 0;
00791 }
00792
00793 typedef enum {
00794 DO_FTP_STAT = 1,
00795 DO_FTP_LSTAT = 2,
00796 DO_FTP_READLINK = 3,
00797 DO_FTP_ACCESS = 4,
00798 DO_FTP_GLOB = 5
00799 } ftpSysCall_t;
00800
00803
00804 static size_t ftpBufAlloced = 0;
00805
00808
00809 static char * ftpBuf = NULL;
00810
00811 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00812
00813
00814 static int ftpNLST(const char * url, ftpSysCall_t ftpSysCall,
00815 struct stat * st,
00816 char * rlbuf, size_t rlbufsiz)
00817
00818
00819 {
00820 FD_t fd;
00821 const char * path;
00822 int bufLength, moretodo;
00823 const char *n, *ne, *o, *oe;
00824 char * s;
00825 char * se;
00826 const char * urldn;
00827 char * bn = NULL;
00828 int nbn = 0;
00829 urlinfo u;
00830 int rc;
00831
00832 n = ne = o = oe = NULL;
00833 (void) urlPath(url, &path);
00834 if (*path == '\0')
00835 return -2;
00836
00837 switch (ftpSysCall) {
00838 case DO_FTP_GLOB:
00839 fd = ftpOpen(url, 0, 0, &u);
00840 if (fd == NULL || u == NULL)
00841 return -1;
00842
00843 u->openError = ftpReq(fd, "NLST", path);
00844 break;
00845 default:
00846 urldn = alloca_strdup(url);
00847
00848 if ((bn = strrchr(urldn, '/')) == NULL)
00849 return -2;
00850 else if (bn == path)
00851 bn = ".";
00852 else
00853 *bn++ = '\0';
00854
00855 nbn = strlen(bn);
00856
00857 rc = ftpChdir(urldn);
00858 if (rc < 0)
00859 return rc;
00860
00861 fd = ftpOpen(url, 0, 0, &u);
00862 if (fd == NULL || u == NULL)
00863 return -1;
00864
00865
00866 u->openError = ftpReq(fd, "NLST", "-la");
00867
00868 if (bn == NULL || nbn <= 0) {
00869 rc = -2;
00870 goto exit;
00871 }
00872 break;
00873 }
00874
00875 if (u->openError < 0) {
00876 fd = fdLink(fd, "error data (ftpStat)");
00877 rc = -2;
00878 goto exit;
00879 }
00880
00881 if (ftpBufAlloced == 0 || ftpBuf == NULL) {
00882 ftpBufAlloced = _url_iobuf_size;
00883 ftpBuf = xcalloc(ftpBufAlloced, sizeof(ftpBuf[0]));
00884 }
00885 *ftpBuf = '\0';
00886
00887 bufLength = 0;
00888 moretodo = 1;
00889
00890 do {
00891
00892
00893 if ((ftpBufAlloced - bufLength) < (1024+80)) {
00894 ftpBufAlloced <<= 2;
00895 ftpBuf = xrealloc(ftpBuf, ftpBufAlloced);
00896 }
00897 s = se = ftpBuf + bufLength;
00898 *se = '\0';
00899
00900 rc = fdFgets(fd, se, (ftpBufAlloced - bufLength));
00901 if (rc <= 0) {
00902 moretodo = 0;
00903 break;
00904 }
00905 if (ftpSysCall == DO_FTP_GLOB) {
00906 bufLength += strlen(se);
00907 continue;
00908 }
00909
00910 for (s = se; *s != '\0'; s = se) {
00911 int bingo;
00912
00913 while (*se && *se != '\n') se++;
00914 if (se > s && se[-1] == '\r') se[-1] = '\0';
00915 if (*se == '\0')
00916 break;
00917 *se++ = '\0';
00918
00919 if (!strncmp(s, "total ", sizeof("total ")-1))
00920 continue;
00921
00922 o = NULL;
00923 for (bingo = 0, n = se; n >= s; n--) {
00924 switch (*n) {
00925 case '\0':
00926 oe = ne = n;
00927 break;
00928 case ' ':
00929 if (o || !(n[-3] == ' ' && n[-2] == '-' && n[-1] == '>')) {
00930 while (*(++n) == ' ')
00931 {};
00932 bingo++;
00933 break;
00934 }
00935 for (o = n + 1; *o == ' '; o++)
00936 {};
00937 n -= 3;
00938 ne = n;
00939 break;
00940 default:
00941 break;
00942 }
00943 if (bingo)
00944 break;
00945 }
00946
00947 if (nbn != (ne - n))
00948 continue;
00949 if (strncmp(n, bn, nbn))
00950 continue;
00951
00952 moretodo = 0;
00953 break;
00954 }
00955
00956 if (moretodo && se > s) {
00957 bufLength = se - s - 1;
00958 if (s != ftpBuf)
00959 memmove(ftpBuf, s, bufLength);
00960 } else {
00961 bufLength = 0;
00962 }
00963 } while (moretodo);
00964
00965 switch (ftpSysCall) {
00966 case DO_FTP_STAT:
00967 if (o && oe) {
00968
00969 }
00970
00971 case DO_FTP_LSTAT:
00972 if (st == NULL || !(n && ne)) {
00973 rc = -1;
00974 } else {
00975 rc = ((vfs_parse_ls_lga(s, st, NULL, NULL) > 0) ? 0 : -1);
00976 }
00977 break;
00978 case DO_FTP_READLINK:
00979 if (rlbuf == NULL || !(o && oe)) {
00980 rc = -1;
00981 } else {
00982 rc = oe - o;
00983 if (rc > rlbufsiz)
00984 rc = rlbufsiz;
00985 memcpy(rlbuf, o, rc);
00986 if (rc < rlbufsiz)
00987 rlbuf[rc] = '\0';
00988 }
00989 break;
00990 case DO_FTP_ACCESS:
00991 rc = 0;
00992 break;
00993 case DO_FTP_GLOB:
00994 rc = 0;
00995 break;
00996 }
00997
00998 exit:
00999 (void) ufdClose(fd);
01000 return rc;
01001 }
01002
01003
01004 static int ftpStat(const char * path, struct stat *st)
01005
01006
01007 {
01008 return ftpNLST(path, DO_FTP_STAT, st, NULL, 0);
01009 }
01010
01011 static int ftpLstat(const char * path, struct stat *st)
01012
01013
01014 {
01015 int rc;
01016 rc = ftpNLST(path, DO_FTP_LSTAT, st, NULL, 0);
01017 if (_rpmio_debug)
01018 fprintf(stderr, "*** ftpLstat(%s) rc %d\n", path, rc);
01019 return rc;
01020 }
01021
01022 static int ftpReadlink(const char * path, char * buf, size_t bufsiz)
01023
01024
01025 {
01026 return ftpNLST(path, DO_FTP_READLINK, NULL, buf, bufsiz);
01027 }
01028
01029 static int ftpGlob(const char * path, int flags,
01030 int errfunc(const char * epath, int eerno),
01031 glob_t * pglob)
01032
01033
01034 {
01035 int rc;
01036
01037 if (pglob == NULL)
01038 return -2;
01039 rc = ftpNLST(path, DO_FTP_GLOB, NULL, NULL, 0);
01040
01041 if (_rpmio_debug)
01042 fprintf(stderr, "*** ftpGlob(%s,0x%x,%p,%p) ftpNLST rc %d\n", path, (unsigned)flags, (void *)errfunc, pglob, rc);
01043
01044 if (rc)
01045 return rc;
01046 rc = poptParseArgvString(ftpBuf, &pglob->gl_pathc, (const char ***)&pglob->gl_pathv);
01047 pglob->gl_offs = -1;
01048 return rc;
01049 }
01050
01051 static void ftpGlobfree(glob_t * pglob)
01052
01053 {
01054
01055 if (_rpmio_debug)
01056 fprintf(stderr, "*** ftpGlobfree(%p)\n", pglob);
01057
01058 if (pglob->gl_offs == -1) {
01059 free((void *)pglob->gl_pathv);
01060 pglob->gl_pathv = NULL;
01061 }
01062 }
01063
01064 int Stat(const char * path, struct stat * st)
01065 {
01066 const char * lpath;
01067 int ut = urlPath(path, &lpath);
01068
01069 if (_rpmio_debug)
01070 fprintf(stderr, "*** Stat(%s,%p)\n", path, st);
01071 switch (ut) {
01072 case URL_IS_FTP:
01073 return ftpStat(path, st);
01074 break;
01075 case URL_IS_HTTP:
01076 case URL_IS_PATH:
01077 path = lpath;
01078
01079 case URL_IS_UNKNOWN:
01080 break;
01081 case URL_IS_DASH:
01082 default:
01083 return -2;
01084 break;
01085 }
01086 return stat(path, st);
01087 }
01088
01089 int Lstat(const char * path, struct stat * st)
01090 {
01091 const char * lpath;
01092 int ut = urlPath(path, &lpath);
01093
01094 if (_rpmio_debug)
01095 fprintf(stderr, "*** Lstat(%s,%p)\n", path, st);
01096 switch (ut) {
01097 case URL_IS_FTP:
01098 return ftpLstat(path, st);
01099 break;
01100 case URL_IS_HTTP:
01101 case URL_IS_PATH:
01102 path = lpath;
01103
01104 case URL_IS_UNKNOWN:
01105 break;
01106 case URL_IS_DASH:
01107 default:
01108 return -2;
01109 break;
01110 }
01111 return lstat(path, st);
01112 }
01113
01114 int Readlink(const char * path, char * buf, size_t bufsiz)
01115 {
01116 const char * lpath;
01117 int ut = urlPath(path, &lpath);
01118
01119 switch (ut) {
01120 case URL_IS_FTP:
01121 return ftpReadlink(path, buf, bufsiz);
01122 break;
01123 case URL_IS_HTTP:
01124 case URL_IS_PATH:
01125 path = lpath;
01126
01127 case URL_IS_UNKNOWN:
01128 break;
01129 case URL_IS_DASH:
01130 default:
01131 return -2;
01132 break;
01133 }
01134 return readlink(path, buf, bufsiz);
01135 }
01136
01137 int Access(const char * path, int amode)
01138 {
01139 const char * lpath;
01140 int ut = urlPath(path, &lpath);
01141
01142 if (_rpmio_debug)
01143 fprintf(stderr, "*** Access(%s,%d)\n", path, amode);
01144 switch (ut) {
01145 case URL_IS_FTP:
01146 case URL_IS_HTTP:
01147 case URL_IS_PATH:
01148 path = lpath;
01149
01150 case URL_IS_UNKNOWN:
01151 break;
01152 case URL_IS_DASH:
01153 default:
01154 return -2;
01155 break;
01156 }
01157 return access(path, amode);
01158 }
01159
01160 int Glob(const char *pattern, int flags,
01161 int errfunc(const char * epath, int eerrno), glob_t *pglob)
01162 {
01163 const char * lpath;
01164 int ut = urlPath(pattern, &lpath);
01165
01166
01167 if (_rpmio_debug)
01168 fprintf(stderr, "*** Glob(%s,0x%x,%p,%p)\n", pattern, (unsigned)flags, (void *)errfunc, pglob);
01169
01170 switch (ut) {
01171 case URL_IS_FTP:
01172 return ftpGlob(pattern, flags, errfunc, pglob);
01173 break;
01174 case URL_IS_HTTP:
01175 case URL_IS_PATH:
01176 pattern = lpath;
01177
01178 case URL_IS_UNKNOWN:
01179 break;
01180 case URL_IS_DASH:
01181 default:
01182 return -2;
01183 break;
01184 }
01185 return glob(pattern, flags, errfunc, pglob);
01186 }
01187
01188 void Globfree(glob_t *pglob)
01189 {
01190 if (_rpmio_debug)
01191 fprintf(stderr, "*** Globfree(%p)\n", pglob);
01192
01193 if (pglob->gl_offs == -1)
01194 ftpGlobfree(pglob);
01195 else
01196 globfree(pglob);
01197
01198 }
01199
01200 DIR * Opendir(const char * path)
01201 {
01202 const char * lpath;
01203 int ut = urlPath(path, &lpath);
01204
01205 if (_rpmio_debug)
01206 fprintf(stderr, "*** Opendir(%s)\n", path);
01207 switch (ut) {
01208 case URL_IS_FTP:
01209 case URL_IS_HTTP:
01210 case URL_IS_PATH:
01211 path = lpath;
01212
01213 case URL_IS_UNKNOWN:
01214 break;
01215 case URL_IS_DASH:
01216 default:
01217 return NULL;
01218 break;
01219 }
01220
01221 return opendir(path);
01222
01223 }
01224
01225
01226 struct dirent * Readdir(DIR * dir)
01227 {
01228 if (_rpmio_debug)
01229 fprintf(stderr, "*** Readdir(%p)\n", (void *)dir);
01230 return readdir(dir);
01231 }
01232
01233 int Closedir(DIR * dir)
01234 {
01235 if (_rpmio_debug)
01236 fprintf(stderr, "*** Closedir(%p)\n", (void *)dir);
01237 return closedir(dir);
01238 }
01239
01240