📄 rfile.c
字号:
/* NEXT_FIELD; f->perm = xstrdup(e);*/ /* the above doesn't work here: * drwxrwxr-x156 31 20 29696 Apr 26 19:00 gnu * ----------^ * so we assume the permission string is exactly 10 characters */ f->perm = xstrndup(cf, 10); cf += 10; /* drwxr-s---+ 78 0 228 1536 Jul 10 15:36 private */ if(*cf == '+') ++cf; NEXT_FIELD; saved_field[0] = xstrdup(e); NEXT_FIELD; saved_field[1] = xstrdup(e); NEXT_FIELD; saved_field[2] = xstrdup(e); NEXT_FIELD; /* special device? */ if(e[strlen(e)-1] == ',') { NEXT_FIELD; } saved_field[3] = xstrdup(e); NEXT_FIELD; saved_field[4] = xstrdup(e); /* distinguish the different ls variants by looking * for the month field */ if(month_number(saved_field[4]) != -1) { /* ls -l */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = saved_field[2]; f->size = strtoull(saved_field[3],NULL,10); free(saved_field[3]); m = saved_field[4]; NEXT_FIELD2; d = xstrdup(e); NEXT_FIELD2; y = xstrdup(e); } else if(month_number(saved_field[3]) != -1) { /* ls -lG */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = xstrdup("group"); f->size = strtoull(saved_field[2],NULL,10); free(saved_field[2]); m = saved_field[3]; d = saved_field[4]; NEXT_FIELD2; y = xstrdup(e); } else if(month_number(saved_field[2]) != -1) { free(saved_field[0]); f->nhl = 0; f->owner = xstrdup("owner");; f->group = xstrdup("group"); f->size = strtoull(saved_field[1],NULL,10); free(saved_field[1]); m = saved_field[2]; d = saved_field[3]; y = saved_field[4]; } else { int iy, im, id, ih = 0, imin = 0; if(sscanf(saved_field[4], "%d-%d-%d", &iy, &im, &id) == 3) { /* date on the form YYYY-MM-DD */ im -= 1; /* should be 0-based */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = saved_field[2]; f->size = strtoull(saved_field[3],NULL,10); free(saved_field[3]); free(saved_field[4]); e = strqsep(&cf, ' '); /* HH:MM */ sscanf(e, "%d:%d", &ih, &imin); { struct tm mt; time_t now; f->mtime = (time_t)-1; mt.tm_sec = 0; mt.tm_min = imin; mt.tm_hour = ih; mt.tm_mday = id; mt.tm_mon = im; mt.tm_year = iy; mt.tm_isdst = -1; f->mtime = mktime(&mt); time(&now); if(f->mtime != (time_t)-1 && (now > f->mtime + 6L * 30L * 24L * 60L * 60L /* Old. */ || now < f->mtime - 60L * 60L)) /* In the future. */ { asprintf(&f->date, "%s %2d %5d", month_name[im], id, iy); } else { asprintf(&f->date, "%s %2d %02d:%02d", month_name[im], id, ih, imin); } time_parsed = true; } } else { free(saved_field[0]); free(saved_field[1]); free(saved_field[2]); free(saved_field[3]); free(saved_field[4]); return -1; } } if(!time_parsed) { asprintf(&f->date, "%s %2s %5s", m, d, y); rfile_parse_time(f, m, d, y); if(f->mtime == (time_t)-1) ftp_trace("rfile_parse_time failed! date == '%s'\n", f->date); free(m); free(d); free(y); } if(!cf) return -1; e = strstr(cf, " -> "); if(e) { *e = 0; f->link = xstrdup(e+4); }#if 0 /* ftp.apple.com: * * drwxr-xr-x 8 0 system 512 Jan 1 22:51 dts * d--x--x--x 2 0 system 512 Sep 12 1997 etc * --------^ * doesn't pad year, so assume filename doesn't start with a space */ /* I've dropped this workaround, 'cause ftp.apple.com seems to * have fixed this, and this prevents a cd to directories with * leading spaces */ while(*cf == ' ') cf++;#endif asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", cf); rfile_parse_colors(f); return 0;}static int rfile_parse_dos(rfile *f, char *str, const char *dirpath){ char *e, *cf = str; char ampm[3]="xx"; int m, d, y, h, mm; NEXT_FIELD; if(sscanf(e, "%d-%d-%d", &m, &d, &y) != 3) return -1; m--; if(y < 70) y += 100; NEXT_FIELD; if(sscanf(e, "%d:%2d%2s", &h, &mm, ampm) != 3) return -1; if(strcasecmp(ampm, "PM") == 0) h += 12; { struct tm mt; f->mtime = (time_t)-1; mt.tm_sec = 0; mt.tm_min = mm; mt.tm_hour = h; mt.tm_mday = d; mt.tm_mon = m; mt.tm_year = y; mt.tm_isdst = -1; f->mtime = mktime(&mt); } { time_t now; time(&now); if(f->mtime != (time_t)-1 && (now > f->mtime + 6L * 30L * 24L * 60L * 60L /* Old. */ || now < f->mtime - 60L * 60L)) /* In the future. */ { asprintf(&f->date, "%s %2d %5d", month_name[m], d, y + 1900); } else { asprintf(&f->date, "%s %2d %02d:%02d", month_name[m], d, h, mm); } } f->perm = xstrdup("-rw-r--r--"); NEXT_FIELD; if(strcasecmp(e, "<DIR>") == 0) { f->perm[0] = 'd'; f->size = 0L; } else { f->size = strtoull(e,NULL,10); } f->nhl = 1; f->owner = xstrdup("owner"); f->group = xstrdup("group"); f->link = 0; while(cf && *cf == ' ') ++cf; asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", cf); rfile_parse_colors(f); return 0;}/* type=cdir;sizd=4096;modify=20010528094249;UNIX.mode=0700;UNIX.uid=1000;UNIX.gid=1000;unique=1642g7c81 . */static int rfile_parse_mlsd(rfile *f, char *str, const char *dirpath){ char *e; bool isdir = false; if(!str) return -1; e = strchr(str, ' '); if(e) { asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", base_name_ptr(e+1)); *e = 0; } else return -1; f->perm = 0; f->size = 0L; f->mtime = 0; f->link = 0; f->nhl = 0; f->owner = xstrdup("owner"); f->group = xstrdup("group"); f->date = xstrdup("Jan 0 1900"); while((e = strqsep(&str, ';')) != 0) { char *factname, *value; factname = strqsep(&e, '='); value = e; if(!factname || !value) { return -1; } if(strcasecmp(factname, "size") == 0 || strcasecmp(factname, "sizd") == 0) /* the "sizd" fact is not standardized in "Extension to * FTP" Internet draft, but PureFTPd uses it for some * reason for size of directories */ f->size = strtoull(value,NULL,10); else if(strcasecmp(factname, "type") == 0) { if(strcasecmp(value, "file") == 0) isdir = false; else if(strcasecmp(value, "dir") == 0 || strcasecmp(value, "cdir") == 0 || strcasecmp(value, "pdir") == 0) isdir = true; } else if(strcasecmp(factname, "modify") == 0) { struct tm ts; sscanf(value, "%04d%02d%02d%02d%02d%02d", &ts.tm_year, &ts.tm_mon, &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); ts.tm_year -= 1900; ts.tm_mon--; f->mtime = gmt_mktime(&ts); free(f->date); f->date = time_to_string(f->mtime); } else if(strcasecmp(factname, "UNIX.mode") == 0) { free(f->perm); f->perm = perm2string(strtoul(value, 0, 8)); } else if(strcasecmp(factname, "UNIX.gid") == 0) { free(f->group); f->group = xstrdup(value); } else if(strcasecmp(factname, "UNIX.uid") == 0) { free(f->owner); f->owner = xstrdup(value); } } if(!f->perm) f->perm = xstrdup("-rw-r--r--"); if(isdir) f->perm[0] = 'd'; rfile_parse_colors(f); return 0;}int rfile_parse(rfile *f, char *str, const char *dirpath, bool is_mlsd){ int i; int r = -1; if(is_mlsd) { char *tmp = xstrdup(str); r = rfile_parse_mlsd(f, tmp, dirpath); free(tmp); return r; } if(ftp->LIST_type == ltUnknown) ftp->LIST_type = ltUnix; for(i=0;i<3;i++) { char *tmp = xstrdup(str); if(ftp->LIST_type == ltUnix) r = rfile_parse_unix(f, tmp, dirpath); else if(ftp->LIST_type == ltDos) r = rfile_parse_dos(f, tmp, dirpath); else if(ftp->LIST_type == ltEplf) r = rfile_parse_eplf(f, tmp, dirpath);/* else if(ftp->LIST_type == ltMlsd) r = rfile_parse_mlsd(f, tmp, dirpath);*/ free(tmp); if(r == -1) { rfile_clear(f); if(ftp->LIST_type == ltUnix) { ftp->LIST_type = ltDos; ftp_trace("UNIX output parsing failed, trying DOS\n"); } else if(ftp->LIST_type == ltDos) { ftp->LIST_type = ltEplf; ftp_trace("DOS output parsing failed, trying EPLF\n"); } else if(ftp->LIST_type == ltEplf) { ftp->LIST_type = ltUnix; ftp_trace("EPLF output parsing failed, trying UNIX\n");/* } else if(ftp->LIST_type == ltMlsd) { ftp->LIST_type = ltUnix; ftp_trace("MLSD output parsing failed, trying UNIX\n");*/ } } else return r; } return -1;}int rfile_search_filename(rfile *f, const char *filename){ return strcmp(base_name_ptr(f->path), filename);}int rfile_search_path(rfile *f, const char *path){ return strcmp(f->path, path);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -