/*****************************************************************************/ /* glist.c CGI-compliant script to list graphics. Call with the path to the directory and it returns a form allowing selection of what graphics are to be displayed. Each directory of graphics is displayed with the a list of subdirectories, the path to each graphic in the directory, and the image generated by the graphic. Image sizes may be specified as using the following form field formats. This allows considerable flexibility in designing form inpur elements for specification of the image dimensions. size='width/height' e.g. size=100 size='width'x'height' size=100x200 size='width'X'height' size=200X100 sizew='width' sizew=200&sizeh=100 sizeh='height' Image sizes may also be specified using the /SIZE[W|H]= qualifiers. PAGE LAYOUT ----------- Page colouration may be specified via the appropriate command-line qualifiers (or corresponding logical name). Defaults for any not specified. Specifiy as /WHATEVER="" to NOT specify the corresponding colour (i.e. leave it to the browser). See "Qualifiers" section below, and also about the logical name "GLIST$PARAM". An example of changing the page colour to white and the banner to red! /PBGCOLOR="#ffffff" /PHBGCOLOR="#ff0000" CGI VARIABLE NAMES ------------------ WWW_FORM_GIF non-null includes GIF images WWW_FORM_JPG non-null includes JPEG images WWW_FORM_LAYOUT integer, list (0) or table width (columns) WWW_FORM_LIST non-null list the directory now WWW_FORM_SIZE integer, image size (pixels, 0 is normal size) WWW_FORM_SIZEX integer, image size (X axis pixels) WWW_FORM_SIZEY integer, image size (Y axis pixels) WWW_FORM_XBM non-null includes X-bitmap images WWW_PATH_INFO the URL path component WWW_PATH_TRANSLATED the VMS equivalent of the URL path component WWW_QUERY_STRING any of the form components WWW_SCRIPT_NAME the name of the script being executed LOGICAL NAMES ------------- GLIST$DBUG turns on all "if (Debug)" statements GLIST$PARAM equivalent to (overrides) the command line parameters/qualifiers (define as a system-wide logical) QUALIFIERS ---------- /BUTTONS= string containing button labels/paths /DBUG turns on all "if (Debug)" statements /LAYOUT default for layout /[NO]ODS5 control extended file specification (basically for testing) /PBACKGROUND=
background image path /PBGCOLOR= background colour /PBBGCOLOR= button background color /PHBGCOLOR= page heading background color /PHLOCAL= local information to be included in header /PHTEXT= page heading text colour /PLAYOUT= 1 is coloured header & buttons, 2 is text & horizontal rules /PLINK= link colour /PTEXT= text colour /PVLINK= visited link colour /SIZE= default for image size /SIZEW= default for image X size (width) /SIZEH= default for image Y size (height) BUILD ----- See BUILD_ONE.COM VERSION HISTORY --------------- 06-OCT-2004 MGD v1.5.0, CGILIB object library 23-DEC-2003 MGD v1.4.2, minor conditional mods to support IA64 12-APR-2003 MGD v1.4.1, link colour changed to 0000cc 20-NOV-2002 MGD v1.4.0, check access to directory contents before listing 15-JUL-2001 MGD v1.3.3, allow image X and Y to be independently specified 28-OCT-2000 MGD v1.3.2, *no changes* (leave this one as a check against the #include variant of CGILIB) 12-APR-2000 MGD v1.3.1, minor changes for CGILIB 1.4 22-JAN-2000 MGD v1.3.0, use CGILIB functionality, support extended file specifications (ODS-5) 08-DEC-1999 MGD v1.2.0, layout and image size 24-JUL-1998 MGD v1.1.1, suppress table background colours if empty 20-MAY-1998 MGD v1.1.0, cosmetic changes 09-FEB-1996 MGD v1.0.0, quick hack */ /*****************************************************************************/ #define SOFTWAREVN "1.5.0" #define SOFTWARENM "GLIST" #ifdef __ALPHA char SoftwareID [64] = SOFTWARENM " AXP-" SOFTWAREVN; #endif #ifdef __ia64 char SoftwareID [64] = SOFTWARENM " IA64-" SOFTWAREVN; #endif #ifdef __VAX char SoftwareID [64] = SOFTWARENM " VAX-" SOFTWAREVN; #endif #ifndef __VAX # pragma nomember_alignment #endif #ifndef __VAX # ifndef NO_ODS_EXTENDED # define ODS_EXTENDED 1 /* this is smaller than the technical maximum, but still quite large! */ # define ODS_MAX_FILE_NAME_LENGTH 511 # define ODS_MAX_FILESYS_NAME_LENGTH 264 # endif #endif #define ODS2_MAX_FILE_NAME_LENGTH 255 #ifndef ODS_MAX_FILE_NAME_LENGTH # define ODS_MAX_FILE_NAME_LENGTH ODS2_MAX_FILE_NAME_LENGTH #endif #if ODS_MAX_FILE_NAME_LENGTH < ODS2_MAX_FILE_NAME_LENGTH # define ODS_MAX_FILE_NAME_LENGTH ODS2_MAX_FILE_NAME_LENGTH #endif #include\n",
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBGCOLOR]);
if (ButtonCount == 0 || !Top1Bottom2)
fprintf (stdout, " \n");
else
{
fprintf (stdout,
"
|
\n\
\n", PageScheme[PS_HEADLOCAL]); } else { fprintf (stdout, "
\n\
\n\
\n\
Graphics Browser\n\
\n\
\n\ \n\ *Glist\n\ \n\ | %s
\n\ \n\\n\
\n"); ButtonBar (2); fprintf (stdout, "\n\n"); } /****************************************************************************/ /* */ ProcessFileSpec () { register char *cptr, *sptr, *zptr; boolean FormatLikeVms, FileOk, JpgGraphic; int status, Bytes, CgiPathTranslatedLength, FileCount = 0, FileGroup = 0, SubdirectoryCount = 0, TotalGif = 0, TotalJpg = 0, TotalXbm = 0; char *GraphicTypePtr, *QuestionMarkPtr, *ResNamePtr, *ResTypePtr, *ResVersionPtr; char HtmlEscPathInfo [ODS_MAX_FILE_NAME_LENGTH+1], DirectoryPath [ODS_MAX_FILE_NAME_LENGTH+1], EscapedTitlePath [ODS_MAX_FILE_NAME_LENGTH+1], ExpFileName [ODS_MAX_FILE_NAME_LENGTH+1], ResFileName [ODS_MAX_FILE_NAME_LENGTH+1], UrlEncDirectoryPath [ODS_MAX_FILE_NAME_LENGTH+1], UrlEncName [ODS_MAX_FILE_NAME_LENGTH+1], UrlEncPathInfo [ODS_MAX_FILE_NAME_LENGTH+1], UrlEncResFileName [ODS_MAX_FILE_NAME_LENGTH+1]; struct FAB SearchFab; struct NAM SearchNam; struct RAB FileRab; #ifdef ODS_EXTENDED char FileSysName [ODS_MAX_FILESYS_NAME_LENGTH+1]; struct NAML SearchNaml; #endif /* ODS_EXTENDED */ /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "ProcessFileSpec()\n"); if (!Layout) FileGroup = 10; else { if (Layout > 5) FileGroup = Layout * 2; else FileGroup = Layout * Layout; } if (CgiQueryStringPtr[0]) QuestionMarkPtr = "?"; else QuestionMarkPtr = ""; CgiPathTranslatedLength = strlen(CgiPathTranslatedPtr); CgiLibHtmlEscape (CgiPathInfoPtr, -1, HtmlEscPathInfo, sizeof(HtmlEscPathInfo)); /* find the directory (i.e. the "/dir1/dir2/" from "/dir1/dir2/*.*") */ zptr = (sptr = DirectoryPath) + sizeof(DirectoryPath)-1; for (cptr = CgiPathInfoPtr; *cptr && sptr < zptr; *sptr++ = *cptr++); if (sptr >= zptr) { CgiLibResponseError (FI_LI, 0, ErrorInternal); exit (SS$_NORMAL); } *sptr = '\0'; FormatLikeVms = false; while (sptr > DirectoryPath && *sptr != '/') { if (*sptr == ';') FormatLikeVms = true; sptr--; } if (sptr > DirectoryPath && *sptr == '/') *++sptr = '\0'; CgiLibUrlEncodeFileName (DirectoryPath, UrlEncDirectoryPath, sizeof(UrlEncDirectoryPath), FormatLikeVms, !FormatLikeVms); CgiLibUrlEncodeFileName (CgiPathInfoPtr, UrlEncPathInfo, sizeof(UrlEncPathInfo), FormatLikeVms, !FormatLikeVms); /***************************/ /* list any subdirectories */ /***************************/ /* initialize the file access block */ SearchFab = cc$rms_fab; #ifdef ODS_EXTENDED if (OdsExtended) { SearchFab.fab$l_dna = SearchFab.fab$l_fna = -1; SearchFab.fab$b_dns = SearchFab.fab$b_fns = 0; SearchFab.fab$l_nam = &SearchNaml; ENAMEL_RMS_NAML(SearchNaml) SearchNaml.naml$l_long_defname = CgiPathTranslatedPtr; SearchNaml.naml$l_long_defname_size = strlen(CgiPathTranslatedPtr); SearchNaml.naml$l_long_filename = "*.DIR"; SearchNaml.naml$l_long_filename_size = 5; SearchNaml.naml$l_long_expand = ExpFileName; SearchNaml.naml$l_long_expand_alloc = sizeof(ExpFileName)-1; SearchNaml.naml$l_long_result = ResFileName; SearchNaml.naml$l_long_result_alloc = sizeof(ResFileName)-1; } else #endif /* ODS_EXTENDED */ { SearchFab.fab$l_dna = CgiPathTranslatedPtr; SearchFab.fab$b_dns = CgiPathTranslatedLength; SearchFab.fab$l_fna = "*.DIR"; SearchFab.fab$b_fns = 5; SearchFab.fab$l_nam = &SearchNam; SearchNam = cc$rms_nam; SearchNam.nam$l_esa = ExpFileName; SearchNam.nam$b_ess = ODS2_MAX_FILE_NAME_LENGTH; SearchNam.nam$l_rsa = ResFileName; SearchNam.nam$b_rss = ODS2_MAX_FILE_NAME_LENGTH; } if (VMSnok (status = sys$parse (&SearchFab, 0, 0))) { CgiLibResponseError (FI_LI, status, HtmlEscPathInfo); exit (SS$_NORMAL); } #ifdef ODS_EXTENDED if (OdsExtended) ResNamePtr = SearchNaml.naml$l_long_name; else #endif /* ODS_EXTENDED */ ResNamePtr = SearchNam.nam$l_name; if (FormatLikeVms) { char c; c = ResNamePtr[0]; ResNamePtr[0] = '\0'; CgiLibHtmlEscape (ExpFileName, -1, EscapedTitlePath, sizeof(EscapedTitlePath)); ResNamePtr[0] = c; } else CgiLibHtmlEscape (DirectoryPath, -1, EscapedTitlePath, sizeof(EscapedTitlePath)); CgiLibResponseHeader (200, "text/html"); fprintf (stdout, "\n\
\n\ \n\ \n\\n\%s\n\
\n", PageScheme[PS_HEADLOCAL], PageScheme[PS_HEADTEXT], EscapedTitlePath); } else { fprintf (stdout, "
\n\
\n\
\n\\n\ \n\ \n\ Graphics Browser\n\ \n\ %s
\n\ \n\ *Glist\n\ \n\\n\%s\n\
\n", PageScheme[PS_HEADBORDER], PageScheme[PS_HEADPADDING], PageScheme[PS_HEADBGCOLOR], PageScheme[PS_HEADTEXT], PageScheme[PS_HEADTEXT], PageScheme[PS_HEADLOCAL], EscapedTitlePath); } while (VMSok (status = sys$search (&SearchFab, 0, 0))) { #ifdef ODS_EXTENDED if (OdsExtended) { ResNamePtr = SearchNaml.naml$l_long_name; ResTypePtr = SearchNaml.naml$l_long_type; ResVersionPtr = SearchNaml.naml$l_long_ver; ResVersionPtr[SearchNaml.naml$l_long_ver_size] = '\0'; } else #endif /* ODS_EXTENDED */ { ResNamePtr = SearchNam.nam$l_name; ResTypePtr = SearchNam.nam$l_type; ResVersionPtr = SearchNam.nam$l_ver; ResVersionPtr[SearchNam.nam$b_ver] = '\0'; } if (Debug) { ResVersionPtr[0] = '\0'; fprintf (stdout, "ResFileName |%s|\n", ResFileName); ResVersionPtr[0] = ';'; } /* can the directory contents be accessed? */ if (VMSnok (status = DirectoryAccess (ResFileName))) continue; if (!SubdirectoryCount++) fprintf (stdout, "
\n\
\n"); if (status != RMS$_FNF && status != RMS$_NMF) { CgiLibResponseError (FI_LI, status, HtmlEscPathInfo); exit (SS$_NORMAL); } /*********************/ /* list any graphics */ /*********************/ /* initialize the file access block */ SearchFab = cc$rms_fab; #ifdef ODS_EXTENDED if (OdsExtended) { SearchFab.fab$l_dna = SearchFab.fab$l_fna = -1; SearchFab.fab$b_dns = SearchFab.fab$b_fns = 0; SearchFab.fab$l_nam = &SearchNaml; ENAMEL_RMS_NAML(SearchNaml) SearchNaml.naml$l_long_defname = CgiPathTranslatedPtr; SearchNaml.naml$l_long_defname_size = strlen(CgiPathTranslatedPtr); SearchNaml.naml$l_long_filename = "*.*"; SearchNaml.naml$l_long_filename_size = 3; SearchNaml.naml$l_long_expand = ExpFileName; SearchNaml.naml$l_long_expand_alloc = sizeof(ExpFileName)-1; SearchNaml.naml$l_long_result = ResFileName; SearchNaml.naml$l_long_result_alloc = sizeof(ResFileName)-1; SearchNaml.naml$l_filesys_name = FileSysName; SearchNaml.naml$l_filesys_name_alloc = sizeof(FileSysName)-1; } else #endif /* ODS_EXTENDED */ { SearchFab.fab$l_dna = CgiPathTranslatedPtr; SearchFab.fab$b_dns = CgiPathTranslatedLength; SearchFab.fab$l_fna = "*.*"; SearchFab.fab$b_fns = 3; SearchFab.fab$l_nam = &SearchNam; SearchNam = cc$rms_nam; SearchNam.nam$l_esa = ExpFileName; SearchNam.nam$b_ess = ODS2_MAX_FILE_NAME_LENGTH; SearchNam.nam$l_rsa = ResFileName; SearchNam.nam$b_rss = ODS2_MAX_FILE_NAME_LENGTH; } if (VMSnok (status = sys$parse (&SearchFab, 0, 0))) { CgiLibResponseError (FI_LI, status, HtmlEscPathInfo); exit (SS$_NORMAL); } while (VMSok (status = sys$search (&SearchFab, 0, 0))) { #ifdef ODS_EXTENDED if (OdsExtended) { ResNamePtr = SearchNaml.naml$l_long_name; ResTypePtr = SearchNaml.naml$l_long_type; ResVersionPtr = SearchNaml.naml$l_long_ver; ResVersionPtr[SearchNaml.naml$l_long_ver_size] = '\0'; } else #endif /* ODS_EXTENDED */ { ResNamePtr = SearchNam.nam$l_name; ResTypePtr = SearchNam.nam$l_type; ResVersionPtr = SearchNam.nam$l_ver; ResVersionPtr[SearchNam.nam$b_ver] = '\0'; } if (Debug) { ResVersionPtr[0] = '\0'; fprintf (stdout, "ResFileName |%s| ResTypePtr |%s|\n", ResFileName, ResTypePtr); ResVersionPtr[0] = ';'; } /* already listed the directories! */ if (strsame (ResTypePtr, ".DIR;", 5)) continue; FileOk = JpgGraphic = false; if (IncludeGif && strsame (ResTypePtr, ".GIF;", 5)) { FileOk = true; TotalGif++; GraphicTypePtr = "GIF"; } if (IncludeJpg) { if (strsame (ResTypePtr, ".JPG;", 5)) { FileOk = JpgGraphic = true; TotalJpg++; GraphicTypePtr = "JPEG"; } if (strsame (ResTypePtr, ".JPEG;", 6)) { FileOk = JpgGraphic = true; TotalJpg++; GraphicTypePtr = "JPEG"; } } if (IncludeXbm && strsame (ResTypePtr, ".XBM;", 5)) { FileOk = true; TotalXbm++; GraphicTypePtr = "X-bitmap"; } if (!FileOk) continue; ResVersionPtr[0] = '\0'; CgiLibUrlEncodeFileName (ResNamePtr, UrlEncName, sizeof(UrlEncName), FormatLikeVms, !FormatLikeVms); ResVersionPtr[0] = ';'; #ifdef ODS_EXTENDED if (OdsExtended) status = FileSize (NULL, &SearchNaml, &Bytes); else status = FileSize (&SearchNam, NULL, &Bytes); #else /* ODS_EXTENDED */ status = FileSize (&SearchNam, &Bytes); #endif /* ODS_EXTENDED */ if (VMSnok (status)) { ResVersionPtr[0] = '\0'; CgiLibUrlEncodeFileName (ResFileName, UrlEncResFileName, sizeof(UrlEncResFileName), FormatLikeVms, !FormatLikeVms); CgiLibResponseError (FI_LI, status, UrlEncResFileName); exit (SS$_NORMAL); } if (!(FileCount % FileGroup)) { if (FileCount) fprintf (stdout, "\n \n"); ResTypePtr[0] = '\0'; if (FormatLikeVms) { CgiLibHtmlEscape (ResNamePtr, -1, UrlEncName, sizeof(UrlEncName)); fprintf (stdout, "[.%s]
\n", CgiScriptNamePtr, UrlEncDirectoryPath, UrlEncName, FormatLikeVms ? ";" : "", QuestionMarkPtr, CgiQueryStringPtr, UrlEncName); } else { CgiLibUrlEncodeFileName (ResNamePtr, UrlEncName, sizeof(UrlEncName), FormatLikeVms, !FormatLikeVms); fprintf (stdout, "./%s/
\n", CgiScriptNamePtr, UrlEncDirectoryPath, UrlEncName, FormatLikeVms ? ";" : "", QuestionMarkPtr, CgiQueryStringPtr, UrlEncName); } ResTypePtr[0] = '.'; } if (SubdirectoryCount) fprintf (stdout, "
\n"); fprintf (stdout, "
\n
\n\ \ GIF: %d \ JPEG: %d \ X-bitmap: %d\ \n", TotalGif, TotalJpg, TotalXbm); } else { fprintf (stdout, "
\n\
\n\ \n\ GIF: %d \ JPEG: %d \ X-bitmap: %d\ \n\ |
No graphics found!\n"); fprintf (stdout, "\n"); ButtonBar (2); fprintf (stdout, "\n\n"); } /*****************************************************************************/ /* */ int DirectoryAccess (char *DirFileName) { int status; char *cptr, *sptr, *zptr; char Directory [ODS_MAX_FILE_NAME_LENGTH+1], ExpFileName [ODS_MAX_FILE_NAME_LENGTH+1], ResFileName [ODS_MAX_FILE_NAME_LENGTH+1]; struct FAB SearchFab; struct NAM SearchNam; #ifdef ODS_EXTENDED struct NAML SearchNaml; #endif /* ODS_EXTENDED */ /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "DirectoryAccess() |%s|\n", DirFileName); zptr = (sptr = Directory) + sizeof(Directory)-1; for (cptr = DirFileName; *cptr && sptr < zptr; *sptr++ = *cptr++); *sptr = '\0'; while (sptr > Directory && *sptr != '.') { while (sptr > Directory && *sptr != '.') sptr--; if (strsame (sptr, ".DIR;", 5)) break; } if (*sptr != '.') { CgiLibResponseError (FI_LI, SS$_BUGCHECK, DirFileName); exit (SS$_NORMAL); } *(unsigned short*)sptr = ']\0'; sptr--; while (sptr > Directory && *sptr != ']' && *sptr != '[') sptr--; if (*sptr == ']') *sptr = '.'; if (Debug) fprintf (stdout, "|%s|\n", Directory); /* initialize the file access block */ SearchFab = cc$rms_fab; #ifdef ODS_EXTENDED if (OdsExtended) { SearchFab.fab$l_dna = SearchFab.fab$l_fna = -1; SearchFab.fab$b_dns = SearchFab.fab$b_fns = 0; SearchFab.fab$l_nam = &SearchNaml; ENAMEL_RMS_NAML(SearchNaml) SearchNaml.naml$l_long_defname = Directory; SearchNaml.naml$l_long_defname_size = strlen(Directory); SearchNaml.naml$l_long_filename = "*.*;"; SearchNaml.naml$l_long_filename_size = 4; SearchNaml.naml$l_long_expand = ExpFileName; SearchNaml.naml$l_long_expand_alloc = sizeof(ExpFileName)-1; SearchNaml.naml$l_long_result = ResFileName; SearchNaml.naml$l_long_result_alloc = sizeof(ResFileName)-1; } else #endif /* ODS_EXTENDED */ { SearchFab.fab$l_dna = Directory; SearchFab.fab$b_dns = strlen(Directory); SearchFab.fab$l_fna = "*.*;"; SearchFab.fab$b_fns = 4; SearchFab.fab$l_nam = &SearchNam; SearchNam = cc$rms_nam; SearchNam.nam$l_esa = ExpFileName; SearchNam.nam$b_ess = ODS2_MAX_FILE_NAME_LENGTH; SearchNam.nam$l_rsa = ResFileName; SearchNam.nam$b_rss = ODS2_MAX_FILE_NAME_LENGTH; } if (VMSnok (status = sys$parse (&SearchFab, 0, 0))) { if (Debug) fprintf (stdout, "sys$parse() %%%08.08X\n", status); return (status); } status = sys$search (&SearchFab, 0, 0); if (Debug) fprintf (stdout, "sys$search() %%%08.08X\n", status); /* release context with a syntax-check only parse */ SearchFab.fab$l_fna = "a:[b]c.d;"; SearchFab.fab$b_fns = 9; SearchFab.fab$b_dns = 0; SearchNam.nam$l_esa = ExpFileName; SearchNam.nam$b_ess = sizeof(ExpFileName)-1; SearchNam.nam$l_rlf = 0; SearchNam.nam$b_nop = NAM$M_SYNCHK; sys$parse (&SearchFab, 0, 0); return (status); } /*****************************************************************************/ /* Convert the integer into an ASCII number string containing commas. Returns a pointer to the string. */ char* CommaNumber (unsigned long Value) { static char Scratch [32], String [32]; static $DESCRIPTOR (ScratchDsc, Scratch); static $DESCRIPTOR (ValueFaoDsc, "!UL"); register int cnt; register char *cptr, *sptr; int status; unsigned short Length; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CommaNumber()\n"); if (VMSnok (status = sys$fao (&ValueFaoDsc, &Length, &ScratchDsc, Value))) return ("*ERROR*"); Scratch[Length] = '\0'; if (((Length-1) / 3) < 1) { cptr = Scratch; sptr = String; while (*cptr) *sptr++ = *cptr++; *sptr = '\0'; return (String); } else if (!(cnt = Length % 3)) cnt = 3; cptr = Scratch; sptr = String; while (*cptr) { if (!cnt--) { *sptr++ = ','; cnt = 2; } *sptr++ = *cptr++; } *sptr = '\0'; return (String); } /*****************************************************************************/ /* This function uses the ACP-QIO interface detailed in the "OpenVMS I/O User's Reference Manual". */ int FileSize ( struct NAM *SearchNamPtr, #ifdef ODS_EXTENDED struct NAML *SearchNamlPtr, #endif /* ODS_EXTENDED */ int *BytesPtr ) { static $DESCRIPTOR (DeviceDsc, ""); static struct { unsigned long OfNoInterest1; unsigned short AllocatedVbnHi; unsigned short AllocatedVbnLo; unsigned short EndOfFileVbnHi; unsigned short EndOfFileVbnLo; unsigned short FirstFreeByte; unsigned short OfNoInterest2; unsigned long OfNoInterestLots [4]; } AtrRecord; #ifdef ODS_EXTENDED /* only use the local ENAMEL.C FIB definition when necessary */ # ifdef ENAMEL_FIBDEF static struct enamel_fibdef FileFib; # else static struct fibdef FileFib; # endif #else /* ODS_EXTENDED */ static struct fibdef FileFib; #endif /* ODS_EXTENDED */ static struct atrdef FileAtr [] = { { sizeof(AtrRecord), ATR$C_RECATTR, &AtrRecord }, { 0, 0, 0 } }; static struct { unsigned short Length; unsigned short Unused; unsigned long Address; } FileNameAcpDsc, FileFibAcpDsc, FileAtrAcpDsc; static struct { unsigned short Status; unsigned short Unused1; unsigned long Unused2; } AcpIOsb; int status; unsigned short AcpChannel; unsigned long AllocatedVbn, EndOfFileVbn; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "FileSize()\n"); /* assign a channel to the disk device containing the file */ #ifdef ODS_EXTENDED if (SearchNamPtr != NULL) { DeviceDsc.dsc$a_pointer = SearchNamPtr->nam$l_dev; DeviceDsc.dsc$w_length = SearchNamPtr->nam$b_dev; } else if (SearchNamlPtr != NULL) { DeviceDsc.dsc$a_pointer = SearchNamlPtr->naml$l_long_dev; DeviceDsc.dsc$w_length = SearchNamlPtr->naml$l_long_dev_size; } #else /* ODS_EXTENDED */ DeviceDsc.dsc$w_length = SearchNamPtr->nam$b_dev; DeviceDsc.dsc$a_pointer = SearchNamPtr->nam$l_dev; #endif /* ODS_EXTENDED */ if (Debug) fprintf (stdout, "|%*.*s|\n", DeviceDsc.dsc$w_length, DeviceDsc.dsc$w_length, DeviceDsc.dsc$a_pointer); status = sys$assign (&DeviceDsc, &AcpChannel, 0, 0, 0); if (Debug) fprintf (stdout, "sys$assign() %%X%08.08X\n", status); if (VMSnok (status)) return (status); /* set up the File Information Block for the ACP interface */ memset (&FileFib, 0, sizeof(struct fibdef)); FileFibAcpDsc.Length = sizeof(FileFib); FileFibAcpDsc.Address = &FileFib; #ifdef ODS_EXTENDED if (SearchNamPtr != NULL) { if (Debug) fprintf (stdout, "EXTENDED NAM\n"); FileFib.fib$w_did[0] = SearchNamPtr->nam$w_did[0]; FileFib.fib$w_did[1] = SearchNamPtr->nam$w_did[1]; FileFib.fib$w_did[2] = SearchNamPtr->nam$w_did[2]; FileNameAcpDsc.Address = SearchNamPtr->nam$l_name; FileNameAcpDsc.Length = SearchNamPtr->nam$b_name + SearchNamPtr->nam$b_type + SearchNamPtr->nam$b_ver; } else if (SearchNamlPtr != NULL) { if (Debug) fprintf (stdout, "EXTENDED NAML\n"); FileFib.fib$w_did[0] = SearchNamlPtr->naml$w_did[0]; FileFib.fib$w_did[1] = SearchNamlPtr->naml$w_did[1]; FileFib.fib$w_did[2] = SearchNamlPtr->naml$w_did[2]; FileNameAcpDsc.Address = SearchNamlPtr->naml$l_filesys_name; FileNameAcpDsc.Length = SearchNamlPtr->naml$l_filesys_name_size; FileFib.fib$b_name_format_in = FIB$C_ISO_LATIN; FileFib.fib$b_name_format_out = FIB$C_ISO_LATIN; FileFib.fib$w_nmctl = FIB$M_NAMES_8BIT; } #else /* ODS_EXTENDED */ if (Debug) fprintf (stdout, "NAM\n"); FileFib.fib$w_did[0] = SearchNamPtr->nam$w_did[0]; FileFib.fib$w_did[1] = SearchNamPtr->nam$w_did[1]; FileFib.fib$w_did[2] = SearchNamPtr->nam$w_did[2]; FileNameAcpDsc.Address = SearchNamPtr->nam$l_name; FileNameAcpDsc.Length = SearchNamPtr->nam$b_name + SearchNamPtr->nam$b_type + SearchNamPtr->nam$b_ver; #endif /* ODS_EXTENDED */ if (Debug) fprintf (stdout, "|%*.*s|\n", FileNameAcpDsc.Length, FileNameAcpDsc.Length, (char*)FileNameAcpDsc.Address); status = sys$qiow (0, AcpChannel, IO$_ACCESS, &AcpIOsb, 0, 0, &FileFibAcpDsc, &FileNameAcpDsc, 0, 0, &FileAtr, 0); /* immediately deassign the channel in case we return on an error */ sys$dassgn (AcpChannel); if (Debug) fprintf (stdout, "sys$qio() %%X%08.08X IOsb: %%X%08.08X\n", status, AcpIOsb.Status); if (VMSok (status)) status = AcpIOsb.Status; if (VMSnok (status)) return (status); AllocatedVbn = AtrRecord.AllocatedVbnLo + (AtrRecord.AllocatedVbnHi << 16); EndOfFileVbn = AtrRecord.EndOfFileVbnLo + (AtrRecord.EndOfFileVbnHi << 16); if (Debug) fprintf (stdout, "AllocatedVbn: %d EndOfFileVbn: %d FirstFreeByte %d\n", AllocatedVbn, EndOfFileVbn, AtrRecord.FirstFreeByte); if (EndOfFileVbn <= 1) *BytesPtr = AtrRecord.FirstFreeByte; else *BytesPtr = ((EndOfFileVbn - 1) << 9) + AtrRecord.FirstFreeByte; if (Debug) fprintf (stdout, "Bytes %d\n", *BytesPtr); return (SS$_NORMAL); } /****************************************************************************/ /* Return an integer reflecting the major and minor version of VMS (e.g. 60, 61, 62, 70, 71, 72, etc.) */ #ifdef ODS_EXTENDED int GetVmsVersion () { static char SyiVersion [16]; static struct { short int buf_len; short int item; unsigned char *buf_addr; unsigned short *ret_len; } SyiItems [] = { { 8, SYI$_VERSION, &SyiVersion, 0 }, { 0,0,0,0 } }; int status, version; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "GetVmsVersion()\n"); if (VMSnok (status = sys$getsyiw (0, 0, 0, &SyiItems, 0, 0, 0))) exit (status); SyiVersion[8] = '\0'; version = ((SyiVersion[1]-48) * 10) + (SyiVersion[3]-48); if (Debug) fprintf (stdout, "|%s| %d\n", SyiVersion, version); return (version); } #endif /* ODS_EXTENDED */ /****************************************************************************/ /* Does a case-insensitive, character-by-character string compare and returns true if two strings are the same, or false if not. If a maximum number of characters are specified only those will be compared, if the entire strings should be compared then specify the number of characters as 0. */ boolean strsame ( register char *sptr1, register char *sptr2, register int count ) { while (*sptr1 && *sptr2) { if (toupper (*sptr1++) != toupper (*sptr2++)) return (false); if (count) if (!--count) return (true); } if (*sptr1 || *sptr2) return (false); else return (true); } /*****************************************************************************/