📄 htvmsutils.c
字号:
/* MODULE HTVMSUtil.c** VMS Utility Routines**** AUTHORS:** MD Mark Donszelmann duns@vxdeop.cern.ch**** HISTORY:** 14 Nov 93 MD Written**** BUGS:*****/#include <HTUtils.h>#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>PUBLIC 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*/PUBLIC BOOL HTVMS_authSysPrv NOARGS{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:***/PUBLIC void HTVMS_enableSysPrv NOARGS{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:***/PUBLIC void HTVMS_disableSysPrv NOARGS{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***/PUBLIC BOOL HTVMS_checkAccess ARGS3( 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*****/PUBLIC char * HTVMS_wwwName ARGS1( 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*/PUBLIC int HTStat ARGS2( 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;PRIVATE DIR *HTVMSopendir(char *dirname);PRIVATE struct dirent *HTVMSreaddir(DIR *dirp);PRIVATE 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 */PRIVATE 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);}PRIVATE struct dirent *HTVMSreaddir(DIR *dirp){static struct dirent entry;long status;struct dsc$descriptor_s entryname_desc;char *space, *slash;char VMSentry[256];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); }}PRIVATE int HTVMSclosedir(DIR *dirp){long status; status = lib$find_file_end(&(dirp->context)); if (!(status & 0x01)) exit(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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -