diff options
author | Thomas E. Dickey <dickey@invisible-island.net> | 2010-04-29 22:00:22 -0400 |
---|---|---|
committer | Thomas E. Dickey <dickey@invisible-island.net> | 2010-04-29 22:00:22 -0400 |
commit | dc748b1c47baadafae2c90f0e188927b11b7e029 (patch) | |
tree | c728869dc6504570b9bffb7459ccbdd1bf264a9f /WWW/Library/Implementation/HTVMSUtils.c | |
parent | d4093cadbda3787dfb165954f8f6521790cfac86 (diff) | |
download | lynx-snapshots-dc748b1c47baadafae2c90f0e188927b11b7e029.tar.gz |
snapshot of project "lynx", label v2_8_8dev_6c
Diffstat (limited to 'WWW/Library/Implementation/HTVMSUtils.c')
-rw-r--r-- | WWW/Library/Implementation/HTVMSUtils.c | 1131 |
1 files changed, 0 insertions, 1131 deletions
diff --git a/WWW/Library/Implementation/HTVMSUtils.c b/WWW/Library/Implementation/HTVMSUtils.c deleted file mode 100644 index a4657760..00000000 --- a/WWW/Library/Implementation/HTVMSUtils.c +++ /dev/null @@ -1,1131 +0,0 @@ - -/* MODULE HTVMSUtil.c - * VMS Utility Routines - * - * AUTHORS: - * MD Mark Donszelmann duns@vxdeop.cern.ch - * - * HISTORY: - * 14 Nov 93 MD Written - * - * BUGS: - * - * - */ - -#include <HTUtils.h> -#ifdef VMS -#include <HTFormat.h> -#include <HTStream.h> -#include <UCDefs.h> -#include <UCMap.h> -#include <UCAux.h> -#include <HTFTP.h> -#include <HTTCP.h> -#include <HTVMSUtils.h> -#include <ssdef.h> -#include <jpidef.h> -#include <prvdef.h> -#include <acldef.h> -#include <chpdef.h> -#include <descrip.h> -#include <lib$routines.h> -#include <starlet.h> -#include <rmsdef.h> - -#include <LYGlobalDefs.h> -#include <LYUtils.h> -#include <LYLeaks.h> -#include <LYStrings.h> - -BOOL HTVMSFileVersions = FALSE; /* Include version numbers in listing? */ - -typedef struct { - unsigned long BufferLength:16; - unsigned long ItemCode:16; - unsigned long BufferAddress:32; - unsigned long ReturnLengthAddress:32; -} ItemStruct; - -/* PUBLIC HTVMS_authSysPrv() - * CHECKS IF THIS PROCESS IS AUTHORIZED TO ENABLE SYSPRV - * ON ENTRY: - * No arguments. - * - * ON EXIT: - * returns YES if SYSPRV is authorized - */ -BOOL HTVMS_authSysPrv(void) -{ - unsigned long Result; - ItemStruct ItemList[2]; - unsigned long Length; - unsigned long Buffer[2]; - - /* fill Item */ - ItemList[0].BufferLength = sizeof(Buffer); - ItemList[0].BufferAddress = (unsigned long) Buffer; - ItemList[0].ReturnLengthAddress = (unsigned long) &Length; - ItemList[0].ItemCode = JPI$_AUTHPRIV; - - /* terminate list */ - ItemList[1].ItemCode = 0; - ItemList[1].BufferLength = 0; - - /* call system */ - Result = sys$getjpiw(0, 0, 0, ItemList, 0, 0, 0); - - if (Result != SS$_NORMAL) - return (NO); - - if (Buffer[0] & PRV$M_SYSPRV) - return (YES); - - return (NO); -} - -/* PUBLIC HTVMS_enableSysPrv() - * ENABLES SYSPRV - * ON ENTRY: - * No arguments. - * - * ON EXIT: - * - */ -void HTVMS_enableSysPrv(void) -{ - unsigned long Result; - unsigned long Prv[2], PreviousPrv[2]; - - Prv[0] = PRV$M_SYSPRV; - Prv[1] = 0; - Result = sys$setprv(1, &Prv, 0, &PreviousPrv); - - if (Result == SS$_NORMAL) { - if (!(PreviousPrv[0] & PRV$M_SYSPRV)) { - CTRACE((tfp, "HTVMS_enableSysPrv: Enabled SYSPRV\n")); - } - } -} - -/* PUBLIC HTVMS_disableSysPrv() - * DISABLES SYSPRV - * ON ENTRY: - * No arguments. - * - * ON EXIT: - * - */ -void HTVMS_disableSysPrv(void) -{ - unsigned long Result; - unsigned long Prv[2], PreviousPrv[2]; - - Prv[0] = PRV$M_SYSPRV; - Prv[1] = 0; - Result = sys$setprv(0, &Prv, 0, &PreviousPrv); - - if (Result == SS$_NORMAL) { - if (PreviousPrv[0] & PRV$M_SYSPRV) { - CTRACE((tfp, "HTVMS_disableSysPrv: Disabled SYSPRV\n")); - } - } -} - -/* PUBLIC HTVMS_checkAccess() - * CHECKS ACCESS TO FILE FOR CERTAIN USER - * ON ENTRY: - * FileName The file to be accessed - * UserName Name of the user to check access for. - * User nobody, represented by "" is given NO for an answer - * Method Name of the method to be chceked - * - * ON EXIT: - * returns YES if access is allowed - * - */ -BOOL HTVMS_checkAccess(const char *FileName, - const char *UserName, - const char *Method) -{ - unsigned long Result; - ItemStruct ItemList[2]; - unsigned long Length; - unsigned long Buffer; - unsigned long ObjType; - - char *VmsName; - - struct dsc$descriptor_s FileNameDesc; - struct dsc$descriptor_s UserNameDesc; - - char *colon; - - /* user nobody should access as from account under which server is running */ - if (0 == strcmp(UserName, "")) - return (NO); - - /* check Filename and convert */ - colon = strchr(FileName, ':'); - if (colon) - VmsName = HTVMS_name("", colon + 1); - else - VmsName = HTVMS_name("", FileName); - - /* check for GET */ - if (0 == strcmp(Method, "GET")) { - /* fill Item */ - ItemList[0].BufferLength = sizeof(Buffer); - ItemList[0].BufferAddress = (unsigned long) &Buffer; - ItemList[0].ReturnLengthAddress = (unsigned long) &Length; - ItemList[0].ItemCode = CHP$_FLAGS; - - /* terminate list */ - ItemList[1].ItemCode = 0; - ItemList[1].BufferLength = 0; - - /* fill input */ - ObjType = ACL$C_FILE; - Buffer = CHP$M_READ; - UserNameDesc.dsc$w_length = strlen(UserName); - UserNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; - UserNameDesc.dsc$b_class = DSC$K_CLASS_S; - UserNameDesc.dsc$a_pointer = (char *) UserName; - FileNameDesc.dsc$w_length = strlen(VmsName); - FileNameDesc.dsc$b_dtype = DSC$K_DTYPE_T; - FileNameDesc.dsc$b_class = DSC$K_CLASS_S; - FileNameDesc.dsc$a_pointer = VmsName; - - /* call system */ - Result = sys$check_access(&ObjType, &FileNameDesc, &UserNameDesc, ItemList); - - if (Result == SS$_NORMAL) - return (YES); - else - return (NO); - } - - return (NO); -} - -/* PUBLIC HTVMS_wwwName() - * CONVERTS VMS Name into WWW Name - * ON ENTRY: - * vmsname VMS file specification (NO NODE) - * - * ON EXIT: - * returns www file specification - * - * EXAMPLES: - * vmsname wwwname - * DISK$USER disk$user - * DISK$USER: /disk$user/ - * DISK$USER:[DUNS] /disk$user/duns - * DISK$USER:[DUNS.ECHO] /disk$user/duns/echo - * [DUNS] duns - * [DUNS.ECHO] duns/echo - * [DUNS.ECHO.-.TRANS] duns/echo/../trans - * [DUNS.ECHO.--.TRANS] duns/echo/../../trans - * [.DUNS] duns - * [.DUNS.ECHO] duns/echo - * [.DUNS.ECHO]TEST.COM duns/echo/test.com - * TEST.COM test.com - * - * - */ -const char *HTVMS_wwwName(const char *vmsname) -{ - static char wwwname[LY_MAXPATH]; - const char *src; - char *dst; - int dir; - - dst = wwwname; - src = vmsname; - dir = 0; - if (strchr(src, ':')) - *(dst++) = '/'; - for (; *src != '\0'; src++) { - switch (*src) { - case ':': - *(dst++) = '/'; - break; - case '-': - if (dir) { - if ((*(src - 1) == '[' || - *(src - 1) == '.' || - *(src - 1) == '-') && - (*(src + 1) == '.' || - *(src + 1) == '-')) { - *(dst++) = '/'; - *(dst++) = '.'; - *(dst++) = '.'; - } else - *(dst++) = '-'; - } else { - if (*(src - 1) == ']') - *(dst++) = '/'; - *(dst++) = '-'; - } - break; - case '.': - if (dir) { - if (*(src - 1) != '[') - *(dst++) = '/'; - } else { - if (*(src - 1) == ']') - *(dst++) = '/'; - *(dst++) = '.'; - } - break; - case '[': - dir = 1; - break; - case ']': - dir = 0; - break; - default: - if (*(src - 1) == ']') - *(dst++) = '/'; - *(dst++) = *src; - break; - } - } - *(dst++) = '\0'; - return (wwwname); -} - -/* - * The code below is for directory browsing by VMS Curses clients. - * It is based on the newer WWWLib's HTDirBrw.c. - Foteos Macrides - */ -int HTStat(const char *filename, - struct stat *info) -{ - /* - the following stuff does not work in VMS with a normal stat... - --> /disk$user/duns/www if www is a directory - is statted like: /disk$user/duns/www.dir - after a normal stat has failed - --> /disk$user/duns if duns is a toplevel directory - is statted like: /disk$user/000000/duns.dir - --> /disk$user since disk$user is a device - is statted like: /disk$user/000000/000000.dir - --> / - searches all devices, no solution yet... - --> /vxcern!/disk$cr/wwwteam/login.com - is not statted but granted with fake information... - */ - int Result; - int Len; - char *Ptr, *Ptr2; - static char *Name; - - /* try normal stat... */ - Result = stat((char *) filename, info); - if (Result == 0) - return (Result); - - /* make local copy */ - StrAllocCopy(Name, filename); - - /* failed,so do device search in case root is requested */ - if (!strcmp(Name, "/")) { /* root requested */ - return (-1); - } - - /* failed so this might be a directory, add '.dir' */ - Len = strlen(Name); - if (Name[Len - 1] == '/') - Name[Len - 1] = '\0'; - - /* fail in case of device */ - Ptr = strchr(Name + 1, '/'); - if ((Ptr == NULL) && (Name[0] == '/')) { /* device only... */ - StrAllocCat(Name, "/000000/000000"); - } - - if (Ptr != NULL) { /* correct filename in case of toplevel dir */ - Ptr2 = strchr(Ptr + 1, '/'); - if ((Ptr2 == NULL) && (Name[0] == '/')) { - char End[256]; - - LYstrncpy(End, Ptr, sizeof(End) - 1); - *(Ptr + 1) = '\0'; - StrAllocCat(Name, "000000"); - StrAllocCat(Name, End); - } - } - - /* try in case a file on toplevel directory or .DIR was already specified */ - Result = stat(Name, info); - if (Result == 0) - return (Result); - - /* add .DIR and try again */ - StrAllocCat(Name, ".dir"); - Result = stat(Name, info); - return (Result); -} - -#ifndef _POSIX_SOURCE -#define d_ino d_fileno /* compatability */ -#ifndef NULL -#define NULL 0 -#endif -#endif /* !_POSIX_SOURCE */ - -typedef struct __dirdesc { - long context; /* context descriptor for LIB$FIND_FILE calls */ - char dirname[255 + 1]; /* keeps the directory name, including *.* */ - struct dsc$descriptor_s dirname_desc; /* descriptor of dirname */ -} DIR; - -static DIR *HTVMSopendir(char *dirname); -static struct dirent *HTVMSreaddir(DIR *dirp); -static int HTVMSclosedir(DIR *dirp); - -/*** #include <sys_dirent.h> ***/ -/*** "sys_dirent.h" ***/ -struct dirent { - unsigned long d_fileno; /* file number of entry */ - unsigned short d_namlen; /* length of string in d_name */ - char d_name[255 + 1]; /* name (up to MAXNAMLEN + 1) */ -}; - -#ifndef _POSIX_SOURCE -/* - * It's unlikely to change, but make sure that sizeof d_name above is - * at least MAXNAMLEN + 1 (more may be added for padding). - */ -#define MAXNAMLEN 255 -/* - * The macro DIRSIZ(dp) gives the minimum amount of space required to represent - * a directory entry. For any directory entry dp->d_reclen >= DIRSIZ(dp). - * Specific filesystem types may use this macro to construct the value - * for d_reclen. - */ -#undef DIRSIZ -#define DIRSIZ(dp) \ - (((sizeof(struct dirent) - (MAXNAMLEN+1) + ((dp)->d_namlen+1)) +3) & ~3) - -#endif /* !_POSIX_SOURCE */ - -static DIR *HTVMSopendir(char *dirname) -{ - static DIR dir; - char *closebracket; - long status; - struct dsc$descriptor_s entryname_desc; - struct dsc$descriptor_s dirname_desc; - static char *DirEntry; - char Actual[256]; - char VMSentry[256]; - char UnixEntry[256]; - int index; - char *dot; - - /* check if directory exists */ - /* dirname can look like /disk$user/duns/www/test/multi */ - /* or like /disk$user/duns/www/test/multi/ */ - /* DirEntry should look like disk$user:[duns.www.test]multi in both cases */ - /* dir.dirname should look like disk$user:[duns.www.test.multi] */ - sprintf(UnixEntry, "%.*s", sizeof(UnixEntry) - 2, dirname); - if (UnixEntry[strlen(UnixEntry) - 1] != '/') - strcat(UnixEntry, "/"); - - StrAllocCopy(DirEntry, HTVMS_name("", UnixEntry)); - if (strlen(DirEntry) > sizeof(dir.dirname) - 1) - return (NULL); - strcpy(dir.dirname, DirEntry); - index = strlen(DirEntry) - 1; - - if (DirEntry[index] == ']') - DirEntry[index] = '\0'; - - if ((dot = strrchr(DirEntry, '.')) == NULL) { /* convert disk$user:[duns] into disk$user:[000000]duns.dir */ - char *openbr = strrchr(DirEntry, '['); - - if (!openbr) { /* convert disk$user: into disk$user:[000000]000000.dir */ - if (strlen(dir.dirname) > sizeof(dir.dirname) - 10) - return (NULL); - sprintf(dir.dirname, "%.*s[000000]", sizeof(dir.dirname) - 9, DirEntry); - StrAllocCat(DirEntry, "[000000]000000.dir"); - } else { - char End[256]; - - strcpy(End, openbr + 1); - *(openbr + 1) = '\0'; - StrAllocCat(DirEntry, "000000]"); - StrAllocCat(DirEntry, End); - StrAllocCat(DirEntry, ".dir"); - } - } else { - *dot = ']'; - StrAllocCat(DirEntry, ".dir"); - } - /* lib$find_file needs a fixed-size buffer */ - LYstrncpy(Actual, DirEntry, sizeof(Actual) - 1); - - dir.context = 0; - dirname_desc.dsc$w_length = strlen(Actual); - dirname_desc.dsc$b_dtype = DSC$K_DTYPE_T; - dirname_desc.dsc$b_class = DSC$K_CLASS_S; - dirname_desc.dsc$a_pointer = (char *) &(Actual); - - /* look for the directory */ - entryname_desc.dsc$w_length = 255; - entryname_desc.dsc$b_dtype = DSC$K_DTYPE_T; - entryname_desc.dsc$b_class = DSC$K_CLASS_S; - entryname_desc.dsc$a_pointer = VMSentry; - - status = lib$find_file(&(dirname_desc), - &entryname_desc, - &(dir.context), - 0, 0, 0, 0); - if (!(status & 0x01)) { /* directory not found */ - return (NULL); - } - - if (strlen(dir.dirname) > sizeof(dir.dirname) - 10) - return (NULL); - if (HTVMSFileVersions) - strcat(dir.dirname, "*.*;*"); - else - strcat(dir.dirname, "*.*"); - dir.context = 0; - dir.dirname_desc.dsc$w_length = strlen(dir.dirname); - dir.dirname_desc.dsc$b_dtype = DSC$K_DTYPE_T; - dir.dirname_desc.dsc$b_class = DSC$K_CLASS_S; - dir.dirname_desc.dsc$a_pointer = (char *) &(dir.dirname); - return (&dir); -} - -static struct dirent *HTVMSreaddir(DIR *dirp) -{ - static struct dirent entry; - long status; - struct dsc$descriptor_s entryname_desc; - char *space, *slash; - char VMSentry[256]; - const char *UnixEntry; - - entryname_desc.dsc$w_length = 255; - entryname_desc.dsc$b_dtype = DSC$K_DTYPE_T; - entryname_desc.dsc$b_class = DSC$K_CLASS_S; - entryname_desc.dsc$a_pointer = VMSentry; - - status = lib$find_file(&(dirp->dirname_desc), - &entryname_desc, - &(dirp->context), - 0, 0, 0, 0); - if (status == RMS$_NMF) { /* no more files */ - return (NULL); - } else { /* ok */ - if (!(status & 0x01)) - return (0); - if (HTVMSFileVersions) - space = strchr(VMSentry, ' '); - else - space = strchr(VMSentry, ';'); - if (space) - *space = '\0'; - - /* convert to unix style... */ - UnixEntry = HTVMS_wwwName(VMSentry); - slash = strrchr(UnixEntry, '/') + 1; - strcpy(entry.d_name, slash); - entry.d_namlen = strlen(entry.d_name); - entry.d_fileno = 1; - return (&entry); - } -} - -static int HTVMSclosedir(DIR *dirp) -{ - long status; - - status = lib$find_file_end(&(dirp->context)); - if (!(status & 0x01)) - exit_immediately(status); - dirp->context = 0; - return (0); -} - -#include <HTAnchor.h> -#include <HTParse.h> -#include <HTBTree.h> -#include <HTFile.h> /* For HTFileFormat() */ -#include <HTAlert.h> -/* - * Hypertext object building machinery. - */ -#include <HTML.h> -#define PUTC(c) (*targetClass.put_character)(target, c) -#define PUTS(s) (*targetClass.put_string)(target, s) -#define START(e) (*targetClass.start_element)(target, e, 0, 0, -1, 0) -#define END(e) (*targetClass.end_element)(target, e, 0) -#define FREE_TARGET (*targetClass._free)(target) -#define ABORT_TARGET (*targetClass._free)(target) -struct _HTStructured { - const HTStructuredClass *isa; - /* ... */ -}; - -#define STRUCT_DIRENT struct dirent - -static char *months[12] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -typedef struct _VMSEntryInfo { - char *filename; - char *type; - char *date; - unsigned int size; - BOOLEAN display; /* show this entry? */ -} VMSEntryInfo; - -static void free_VMSEntryInfo_contents(VMSEntryInfo * entry_info) -{ - if (entry_info) { - FREE(entry_info->filename); - FREE(entry_info->type); - FREE(entry_info->date); - } - /* dont free the struct */ -} - -int compare_VMSEntryInfo_structs(VMSEntryInfo * entry1, VMSEntryInfo * 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 (strcasecomp(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 (strcasecomp(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) { - return (strcasecomp(entry1->filename, - entry2->filename)); - } - /* - * Set up for sorting in reverse - * chronological order. - FM - */ - if (entry1->date[7] != ' ') { - strcpy(date1, "9999"); - strcpy(time1, (char *) &entry1->date[7]); - } else { - strcpy(date1, (char *) &entry1->date[8]); - strcpy(time1, "00:00"); - } - strncpy(month, entry1->date, 3); - month[3] = '\0'; - for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { - break; - } - } - i++; - sprintf(month, "%02d", i); - strcat(date1, month); - strncat(date1, (char *) &entry1->date[4], 2); - date1[8] = '\0'; - if (date1[6] == ' ') { - date1[6] = '0'; - } - strcat(date1, time1); - if (entry2->date[7] != ' ') { - strcpy(date2, "9999"); - strcpy(time2, (char *) &entry2->date[7]); - } else { - strcpy(date2, (char *) &entry2->date[8]); - strcpy(time2, "00:00"); - } - strncpy(month, entry2->date, 3); - month[3] = '\0'; - for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { - break; - } - } - i++; - sprintf(month, "%02d", i); - strcat(date2, month); - strncat(date2, (char *) &entry2->date[4], 2); - date2[8] = '\0'; - if (date2[6] == ' ') { - date2[6] = '0'; - } - strcat(date2, time2); - /* - * Do the comparison. - FM - */ - status = strcasecomp(date2, date1); - if (status) - return (status); - /* else fall to filename comparison */ - } - return (strcasecomp(entry1->filename, - entry2->filename)); - case FILE_BY_NAME: - default: - return (strcmp(entry1->filename, - entry2->filename)); - } -} - -/* HTVMSBrowseDir() - * - * This function generates a directory listing as an HTML-object - * for local file URL's. It assumes the first two elements of - * of the path are a device followed by a directory: - * - * file://localhost/device/directory[/[foo]] - * - * Will not accept 000000 as a directory name. - * Will offer links to parent through the top directory, unless - * a terminal slash was included in the calling URL. - * - * Returns HT_LOADED on success, HTLoadError() messages on error. - * - * Developed for Lynx by Foteos Macrides (macrides@sci.wfeb.edu). - */ -int HTVMSBrowseDir(const char *address, - HTParentAnchor *anchor, - HTFormat format_out, - HTStream *sink) -{ - HTStructured *target; - HTStructuredClass targetClass; - char *pathname = HTParse(address, "", PARSE_PATH + PARSE_PUNCTUATION); - char *tail = NULL; - char *title = NULL; - char *header = NULL; - char *parent = NULL; - char *relative = NULL; - char *cp, *cp1; - int pathend, len; - DIR *dp; - struct stat file_info; - time_t NowTime; - static char ThisYear[8]; - VMSEntryInfo *entry_info = 0; - char string_buffer[64]; - - HTUnEscape(pathname); - CTRACE((tfp, "HTVMSBrowseDir: Browsing `%s\'\n", pathname)); - - /* - * Require at least two elements (presumably a device and directory) and - * disallow the device root (000000 directory). Symbolic paths (e.g., - * sys$help) should have been translated and expanded (e.g., to - * /sys$sysroot/syshlp) before calling this routine. - */ - if (((*pathname != '/') || - (cp = strchr(pathname + 1, '/')) == NULL || - *(cp + 1) == '\0' || - 0 == strncmp((cp + 1), "000000", 6)) || - (dp = HTVMSopendir(pathname)) == NULL) { - FREE(pathname); - return HTLoadError(sink, 403, COULD_NOT_ACCESS_DIR); - } - - /* - * Set up the output stream. - */ - _HTProgress(BUILDING_DIR_LIST); - if (UCLYhndl_HTFile_for_unspec >= 0) { - HTAnchor_setUCInfoStage(anchor, - UCLYhndl_HTFile_for_unspec, - UCT_STAGE_PARSER, - UCT_SETBY_DEFAULT); - } - target = HTML_new(anchor, format_out, sink); - targetClass = *(target->isa); - - /* - * Set up the offset string of the anchor reference, and strings for the - * title and header. - */ - cp = strrchr(pathname, '/'); /* find lastslash */ - StrAllocCopy(tail, (cp + 1)); /* take slash off the beginning */ - if (*tail != '\0') { - StrAllocCopy(title, tail); - *cp = '\0'; - if ((cp1 = strrchr(pathname, '/')) != NULL && - cp1 != pathname && - strncmp((cp1 + 1), "000000", 6)) - StrAllocCopy(parent, (cp1 + 1)); - *cp = '/'; - } else { - pathname[strlen(pathname) - 1] = '\0'; - cp = strrchr(pathname, '/'); - StrAllocCopy(title, (cp + 1)); - pathname[strlen(pathname)] = '/'; - } - StrAllocCopy(header, pathname); - - /* - * Initialize path name for HTStat(). - */ - pathend = strlen(pathname); - if (*(pathname + pathend - 1) != '/') { - StrAllocCat(pathname, "/"); - pathend++; - } - - /* - * Output the title and header. - */ - START(HTML_HTML); - PUTC('\n'); - START(HTML_HEAD); - PUTC('\n'); - HTUnEscape(title); - START(HTML_TITLE); - PUTS(title); - PUTS(" directory"); - END(HTML_TITLE); - PUTC('\n'); - FREE(title); - END(HTML_HEAD); - PUTC('\n'); - START(HTML_BODY); - PUTC('\n'); - HTUnEscape(header); - START(HTML_H1); - PUTS(header); - END(HTML_H1); - PUTC('\n'); - if (HTDirReadme == HT_DIR_README_TOP) { - FILE *fp; - - if (header[strlen(header) - 1] != '/') - StrAllocCat(header, "/"); - StrAllocCat(header, HT_DIR_README_FILE); - if ((fp = fopen(header, "r")) != NULL) { - START(HTML_PRE); - for (;;) { - char c = fgetc(fp); - - if (c == (char) EOF) - break; -#ifdef NOTDEFINED - switch (c) { - case '&': - case '<': - case '>': - PUTC('&'); - PUTC('#'); - PUTC((char) (c / 10)); - PUTC((char) (c % 10)); - PUTC(';'); - break; - default: - PUTC(c); - } -#else - PUTC(c); -#endif /* NOTDEFINED */ - } - END(HTML_PRE); - fclose(fp); - } - } - FREE(header); - if (parent) { - HTSprintf0(&relative, "%s/..", tail); - HTStartAnchor(target, "", relative); - PUTS("Up to "); - HTUnEscape(parent); - PUTS(parent); - END(HTML_A); - START(HTML_P); - PUTC('\n'); - FREE(relative); - FREE(parent); - } - - /* - * Set up the date comparison. - */ - NowTime = time(NULL); - strcpy(ThisYear, (char *) ctime(&NowTime) + 20); - ThisYear[4] = '\0'; - - /* - * Now, generate the Btree and put it out to the output stream. - */ - { - char dottest = 2; /* To avoid two strcmp() each time */ - STRUCT_DIRENT *dirbuf; - HTBTree *bt; - - /* Set up sort key and initialize BTree */ - bt = HTBTree_new((HTComparer) compare_VMSEntryInfo_structs); - - /* Build tree */ - while ((dirbuf = HTVMSreaddir(dp))) { - HTAtom *encoding = NULL; - HTFormat format; - - /* Skip if not used */ - if (!dirbuf->d_ino) { - continue; - } - - /* Current and parent directories are never shown in list */ - if (dottest && (!strcmp(dirbuf->d_name, ".") || - !strcmp(dirbuf->d_name, ".."))) { - dottest--; - continue; - } - - /* Don't show the selective enabling file - * unless version numbers are included */ - if (!strcasecomp(dirbuf->d_name, HT_DIR_ENABLE_FILE)) { - continue; - } - - /* Skip files beginning with a dot? */ - if ((no_dotfiles || !show_dotfiles) && *dirbuf->d_name == '.') { - continue; - } - - /* OK, make an lstat() and get a key ready. */ - *(pathname + pathend) = '\0'; - StrAllocCat(pathname, dirbuf->d_name); - if (HTStat(pathname, &file_info)) { - /* for VMS the failure here means the file is not readable... - we however continue to browse through the directory... */ - continue; - } - entry_info = (VMSEntryInfo *) malloc(sizeof(VMSEntryInfo)); - if (entry_info == NULL) - outofmem(__FILE__, "HTVMSBrowseDir"); - entry_info->type = 0; - entry_info->size = 0; - entry_info->date = 0; - entry_info->filename = 0; - entry_info->display = TRUE; - - /* Get the type */ - format = HTFileFormat(dirbuf->d_name, &encoding, - (const char **) &cp); - if (!cp) { - if (!strncmp(HTAtom_name(format), "application", 11)) { - cp = HTAtom_name(format) + 12; - if (!strncmp(cp, "x-", 2)) - cp += 2; - } else - cp = HTAtom_name(format); - } - StrAllocCopy(entry_info->type, cp); - - StrAllocCopy(entry_info->filename, dirbuf->d_name); - if (S_ISDIR(file_info.st_mode)) { - /* strip .DIR part... */ - char *dot; - - dot = strstr(entry_info->filename, ".DIR"); - if (dot) - *dot = '\0'; - LYLowerCase(entry_info->filename); - StrAllocCopy(entry_info->type, "Directory"); - } else { - if ((cp = strstr(entry_info->filename, "READ")) == NULL) { - cp = entry_info->filename; - } else { - cp += 4; - if (!strncmp(cp, "ME", 2)) { - cp += 2; - while (cp && *cp && *cp != '.') { - cp++; - } - } else if (!strncmp(cp, ".ME", 3)) { - cp = (entry_info->filename + - strlen(entry_info->filename)); - } else { - cp = entry_info->filename; - } - } - LYLowerCase(cp); - if (((len = strlen(entry_info->filename)) > 2) && - entry_info->filename[len - 1] == 'z') { - if (entry_info->filename[len - 2] == '.' || - entry_info->filename[len - 2] == '_') - entry_info->filename[len - 1] = 'Z'; - } - } - - /* Get the date */ - { - char *t = (char *) ctime((const time_t *) &file_info.st_ctime); - - *(t + 24) = '\0'; - - StrAllocCopy(entry_info->date, (t + 4)); - *((entry_info->date) + 7) = '\0'; - if ((atoi((t + 19))) < atoi(ThisYear)) - StrAllocCat(entry_info->date, (t + 19)); - else { - StrAllocCat(entry_info->date, (t + 11)); - *((entry_info->date) + 12) = '\0'; - } - } - - /* Get the size */ - if (!S_ISDIR(file_info.st_mode)) - entry_info->size = (unsigned int) file_info.st_size; - else - entry_info->size = 0; - - /* Now, update the BTree etc. */ - if (entry_info->display) { - CTRACE((tfp, "Adding file to BTree: %s\n", - entry_info->filename)); - HTBTree_add(bt, entry_info); - } - - } /* End while HTVMSreaddir() */ - - FREE(pathname); - HTVMSclosedir(dp); - - START(HTML_PRE); - /* - * Run through the BTree printing out in order - */ - { - HTBTElement *ele; - int i; - - for (ele = HTBTree_next(bt, NULL); - ele != NULL; - ele = HTBTree_next(bt, ele)) { - entry_info = (VMSEntryInfo *) HTBTree_object(ele); - - /* Output the date */ - if (entry_info->date) { - PUTS(entry_info->date); - PUTS(" "); - } else - PUTS(" * "); - - /* Output the type */ - if (entry_info->type) { - for (i = 0; entry_info->type[i] != '\0' && i < 15; i++) - PUTC(entry_info->type[i]); - for (; i < 17; i++) - PUTC(' '); - - } - - /* Output the link for the name */ - HTDirEntry(target, tail, entry_info->filename); - PUTS(entry_info->filename); - END(HTML_A); - - /* Output the size */ - if (entry_info->size) { - if (entry_info->size < 1024) - sprintf(string_buffer, " %d bytes", - entry_info->size); - else - sprintf(string_buffer, " %dKb", - entry_info->size / 1024); - PUTS(string_buffer); - } - - PUTC('\n'); /* end of this entry */ - - free_VMSEntryInfo_contents(entry_info); - } - } - - HTBTreeAndObject_free(bt); - - } /* End of both BTree loops */ - - /* - * Complete the output stream. - */ - END(HTML_PRE); - PUTC('\n'); - END(HTML_BODY); - PUTC('\n'); - END(HTML_HTML); - PUTC('\n'); - FREE(tail); - FREE_TARGET; - - return HT_LOADED; - -} /* End of directory reading section */ - -/* - * Remove all versions of the given file. We assume there are no permissions - * problems, since we do this mainly for removing temporary files. - */ -int HTVMS_remove(char *filename) -{ - int code = remove(filename); /* return the first status code */ - - while (remove(filename) == 0) ; - return code; -} - -/* - * Remove all older versions of the given file. We may fail to remove some - * version due to permissions -- the loop stops either at that point, or when - * we run out of older versions to remove. - */ -void HTVMS_purge(char *filename) -{ - char *older_file = 0; - char *oldest_file = 0; - struct stat sb; - - StrAllocCopy(older_file, filename); - StrAllocCat(older_file, ";-1"); - - while (remove(older_file) == 0) ; - /* - * If we do not have any more older versions, it is safe to rename the - * current file to version #1. - */ - if (stat(older_file, &sb) != 0) { - StrAllocCopy(oldest_file, filename); - StrAllocCat(oldest_file, ";1"); - rename(older_file, oldest_file); - FREE(oldest_file); - } - - FREE(older_file); -} -#endif /* VMS */ |