📄 htftp.c
字号:
EntryInfo *, entry_info){ char *cp = line; char *cps, *cpd, date[16]; char *end = line + strlen(line); int RecordLength = 0; int Records = 0; int i; /** Get rid of blank or junk lines. **/ cp = LYSkipBlanks(cp); if (!(*cp)) { entry_info->display = FALSE; return; } /** Cut out file or directory name. **/ cps = LYSkipNonBlanks(cp); *cps++ ='\0'; StrAllocCopy(entry_info->filename, cp); if (strchr(entry_info->filename, '.') != NULL) /** If we already have a dot, we did an NLST. **/ return; cp = LYSkipBlanks(cps); if (!(*cp)) { /** If we don't have more, we've misparsed. **/ FREE(entry_info->filename); FREE(entry_info->type); entry_info->display = FALSE; return; } cps = LYSkipNonBlanks(cp); *cps++ ='\0'; if ((0 == strcasecomp(cp, "DIR")) && (cp - line) > 17) { /** It's an SFS directory. **/ StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); entry_info->size = 0; } else { /** It's a file. **/ cp--; *cp = '.'; StrAllocCat(entry_info->filename, cp); /** Track down the VM/CMS RECFM or type. **/ cp = cps; if (cp < end) { cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; /** Check cp here, if it's relevant someday. **/ } } /** Track down the record length or dash. **/ cp = cps; if (cp < end) { cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; if (isdigit(UCH(*cp))) { RecordLength = atoi(cp); } } /** Track down the number of records or the dash. **/ cp = cps; if (cps < end) { cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; if (isdigit(UCH(*cp))) { Records = atoi(cp); } if (Records > 0 && RecordLength > 0) { /** Compute an approximate size. **/ entry_info->size = (Records * RecordLength); } } /** Set the years and date, if we don't have them yet. **/ if (!HaveYears) { set_years_and_date(); } /** Track down the date. **/ cpd = cps; if (((cps < end) && (cps = strchr(cpd, ':')) != NULL) && (cps < (end - 3) && isdigit(UCH(*(cps+1))) && isdigit(UCH(*(cps+2))) && *(cps+3) == ':')) { cps += 3; *cps = '\0'; if ((cps - cpd) >= 14) { cpd = (cps - 14); *(cpd+2) = '\0'; /* Month */ *(cpd+5) = '\0'; /* Day */ *(cpd+8) = '\0'; /* Year */ cps -= 5; /* Time */ if (*cpd == ' ') *cpd = '0'; i = atoi(cpd) - 1; sprintf(date, "%.3s %.2s", months[i], (cpd+3)); if (date[4] == '0') date[4] = ' '; cpd += 6; /* Year */ if (strcmp((ThisYear+2), cpd)) { /* Not this year, so show the year. */ if (atoi(cpd) < 70) { sprintf(&date[6], " 20%.2s", cpd); } else { sprintf(&date[6], " 19%.2s", cpd); } } else { /* Is this year, so show the time. */ *(cps+2) = '\0'; /* Hour */ i = atoi(cps); sprintf(&date[6], " %02d:%.2s", i, (cps+3)); } StrAllocCopy(entry_info->date, date); if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { entry_info->date[4] = HT_NON_BREAK_SPACE; } } } /** Wrap it up. **/ CTRACE((tfp, "HTFTP: VM/CMS filename: %s date: %s size: %d\n", entry_info->filename, NonNull(entry_info->date), entry_info->size)); return;} /* parse_cms_dir_entry *//* * parse_dir_entry() * Given a line of LIST/NLST output in entry, return results * and a file/dir name in entry_info struct * * If first is true, this is the first name in a directory. */PRIVATE EntryInfo * parse_dir_entry ARGS3( char *, entry, BOOLEAN *, first, char **, pspilledname){ EntryInfo *entry_info; int i; int len; BOOLEAN remove_size=FALSE; char *cp; entry_info = (EntryInfo *)malloc(sizeof(EntryInfo)); if (entry_info == NULL) outofmem(__FILE__, "parse_dir_entry"); entry_info->filename = NULL; entry_info->type = NULL; entry_info->date = NULL; entry_info->size = 0; entry_info->display = TRUE; switch (server_type) { case DLS_SERVER: /* ** Interpret and edit LIST output from a Unix server ** in "dls" format. ** This one must have claimed to be Unix in order to ** get here; if the first line looks fishy, we revert ** to Unix and hope that fits better (this recovery is ** untested). - kw */ if (*first) { len = strlen(entry); if (!len || entry[0] == ' ' || (len >= 24 && entry[23] != ' ') || (len < 24 && strchr(entry, ' '))) { server_type = UNIX_SERVER; CTRACE((tfp, "HTFTP: Falling back to treating as Unix server.\n")); } else { *first = FALSE; } } if (server_type == DLS_SERVER) { /* if still unchanged... */ parse_dls_line(entry, entry_info, pspilledname); if (!entry_info->filename || *entry_info->filename == '\0') { entry_info->display = FALSE; return(entry_info); } if (!strcmp(entry_info->filename,"..") || !strcmp(entry_info->filename,".")) entry_info->display = FALSE; if (entry_info->type && *entry_info->type == '\0') { FREE(entry_info->type); return(entry_info); } /* ** Goto the bottom and get real type. */ break; } /* fall through if server_type changed for *first == TRUE ! */ case UNIX_SERVER: case PETER_LEWIS_SERVER: case MACHTEN_SERVER: case MSDOS_SERVER: case WINDOWS_NT_SERVER: case WINDOWS_2K_SERVER: case APPLESHARE_SERVER: case NETPRESENZ_SERVER: /* ** Check for EPLF output (local times). */ if (*entry == '+') { parse_eplf_line(entry, entry_info); break; } /* ** Interpret and edit LIST output from Unix server. */ len = strlen(entry); if (*first) { /* don't gettext() this -- incoming text: */ if (!strcmp(entry, "can not access directory .")) { /* * Don't reset *first, nothing real will follow. - KW */ entry_info->display = FALSE; return(entry_info); } *first = FALSE; if (!strncmp(entry, "total ", 6) || strstr(entry, "not available") != NULL) { entry_info->display = FALSE; return(entry_info); } else if (unsure_type) { /* this isn't really a unix server! */ server_type = GENERIC_SERVER; entry_info->display = FALSE; return(entry_info); } } /* ** Check first character of ls -l output. */ if (TOUPPER(entry[0]) == 'D') { /* ** It's a directory. */ StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); remove_size=TRUE; /* size is not useful */ } else if (entry[0] == 'l') { /* ** It's a symbolic link, does the user care about ** knowing if it is symbolic? I think so since ** it might be a directory. */ StrAllocCopy(entry_info->type, gettext("Symbolic Link")); remove_size=TRUE; /* size is not useful */ /* ** Strip off " -> pathname". */ for (i = len - 1; (i > 3) && (!isspace(UCH(entry[i])) || (entry[i-1] != '>') || (entry[i-2] != '-') || (entry[i-3] != ' ')); i--) ; /* null body */ if (i > 3) { entry[i-3] = '\0'; len = i - 3; } } /* link */ parse_ls_line(entry, entry_info); if (!strcmp(entry_info->filename,"..") || !strcmp(entry_info->filename,".")) entry_info->display = FALSE; /* ** Goto the bottom and get real type. */ break; case VMS_SERVER: /* ** Interpret and edit LIST output from VMS server ** and convert information lines to zero length. */ parse_vms_dir_entry(entry, entry_info); /* ** Get rid of any junk lines. */ if (!entry_info->display) return(entry_info); /* ** Trim off VMS directory extensions. */ len = strlen(entry_info->filename); if ((len > 4) && !strcmp(&entry_info->filename[len-4], ".dir")) { entry_info->filename[len-4] = '\0'; StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); remove_size=TRUE; /* size is not useful */ } /* ** Goto the bottom and get real type. */ break; case MS_WINDOWS_SERVER: /* ** Interpret and edit LIST output from MS_WINDOWS server ** and convert information lines to zero length. */ parse_ms_windows_dir_entry(entry, entry_info); /* ** Get rid of any junk lines. */ if (!entry_info->display) return(entry_info); if (entry_info->type && *entry_info->type == '\0') { FREE(entry_info->type); return(entry_info); } /* ** Goto the bottom and get real type. */ break;#ifdef NOTDEFINED case WINDOWS_NT_SERVER: /* ** Interpret and edit LIST output from MS_WINDOWS server ** and convert information lines to zero length. */ parse_windows_nt_dir_entry(entry, entry_info); /* ** Get rid of any junk lines. */ if (!entry_info->display) return(entry_info); if (entry_info->type && *entry_info->type == '\0') { FREE(entry_info->type); return(entry_info); } /* ** Goto the bottom and get real type. */ break;#endif /* NOTDEFINED */ case CMS_SERVER: { /* ** Interpret and edit LIST output from VM/CMS server ** and convert any information lines to zero length. */ parse_cms_dir_entry(entry, entry_info); /* ** Get rid of any junk lines. */ if (!entry_info->display) return(entry_info); if (entry_info->type && *entry_info->type == '\0') { FREE(entry_info->type); return(entry_info); } /* ** Goto the bottom and get real type. */ break; } case NCSA_SERVER: case TCPC_SERVER: /* ** Directories identified by trailing "/" characters. */ StrAllocCopy(entry_info->filename, entry); len = strlen(entry); if (entry[len-1] == '/') { /* ** It's a dir, remove / and mark it as such. */ entry[len-1] = '\0'; StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); remove_size=TRUE; /* size is not useful */ } /* ** Goto the bottom and get real type. */ break; default: /* ** We can't tell if it is a directory since we only ** did an NLST :( List bad file types anyways? NOT! */ StrAllocCopy(entry_info->filename, entry); return(entry_info); /* mostly empty info */ } /* switch (server_type) */ if (remove_size && entry_info->size) { entry_info->size = 0; } if (entry_info->filename && strlen(entry_info->filename) > 3) { if (((cp=strrchr(entry_info->filename, '.')) != NULL && 0 == strncasecomp(cp, ".me", 3)) && (cp[3] == '\0' || cp[3] == ';')) { /* ** Don't treat this as application/x-Troff-me ** if it's a Unix server but has the string ** "read.me", or if it's not a Unix server. - FM */ if ((server_type != UNIX_SERVER) || (cp > (entry_info->filename + 3) && 0 == strncasecomp((cp - 4), "read.me", 7))) { StrAllocCopy(entry_info->type, "text/plain"); } } } /* ** Get real types eventually. */ if (!entry_info->type) { CONST char *cp2; HTFormat format; HTAtom * encoding; /* @@ not used at all */ format = HTFileFormat(entry_info->filename, &encoding, &cp2); if (cp2 == NULL) { if (!strncmp(HTAtom_name(format), "application",11)) { cp2 = HTAtom_name(format) + 12; if (!strncmp(cp2,"x-",2)) cp2 += 2; } else { cp2 = HTAtom_name(format); } } StrAllocCopy(entry_info->type, cp2); } return(entry_info);} /* parse_dir_entry */PRIVATE int compare_EntryInfo_structs ARGS2( EntryInfo *, entry1, EntryInfo *, entry2){ int i, status; char date1[16], date2[16], time1[8], time2[8], month[4]; switch(HTfileSortMethod) { case FILE_BY_SIZE: /* both equal or both 0 */ if (entry1->size == entry2->size) return(strcmp(entry1->filename, entry2->filename)); else if (entry1->size > entry2->size) return(1); else return(-1); case FILE_BY_TYPE: if (entry1->type && entry2->type) { status = strcasecomp(entry1->type, entry2->type); if (status) return(status); /* else fall to filename comparison */ } return (strcmp(entry1->filename, entry2->filename)); case FILE_BY_DATE: if (entry1->date && entry2->date) { /* ** Make sure we have the correct length. - FM */ if (strlen(entry1->date) != 12 || strlen(entry2->date) != 12) { r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -