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