/* * LoaderUtilsImpl.c * bj, August 4, 1989 9:12:48 pm PDT * eduardo, November 20, 1989 10:29:52 am PST * cc -c -g -I/jaune/xrhome/INSTALLED/INCLUDE/ LoaderUtilsImpl.c */ #include #define stdout XR_MSG_STDOUT /* #include */ #define _U 01 #define _L 02 #define _N 04 #define _S 010 #define _P 020 #define _C 040 #define _X 0100 #define _B 0200 static char _ctype_[] = { 0, /* 0 1 2 3 4 5 6 7 */ /* 0*/ _C, _C, _C, _C, _C, _C, _C, _C, /* 10*/ _C, _S|_C, _S|_C, _S|_C, _S|_C, _S|_C, _C, _C, /* 20*/ _C, _C, _C, _C, _C, _C, _C, _C, /* 30*/ _C, _C, _C, _C, _C, _C, _C, _C, /* 40*/ _S|_B, _P, _P, _P, _P, _P, _P, _P, /* 50*/ _P, _P, _P, _P, _P, _P, _P, _P, /* 60*/ _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, _N|_X, /* 70*/ _N|_X, _N|_X, _P, _P, _P, _P, _P, _P, /*100*/ _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, /*110*/ _U, _U, _U, _U, _U, _U, _U, _U, /*120*/ _U, _U, _U, _U, _U, _U, _U, _U, /*130*/ _U, _U, _U, _P, _P, _P, _P, _P, /*140*/ _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, /*150*/ _L, _L, _L, _L, _L, _L, _L, _L, /*160*/ _L, _L, _L, _L, _L, _L, _L, _L, /*170*/ _L, _L, _L, _P, _P, _P, _P, _C, /*200*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define isupper(c) ((_ctype_+1)[c]&_U) #define tolower(c) ((c)-'A'+'a') #include #include #include #include #include #include #include #include "XREnviron.h" #include "LoaderUtils.h" /* missing interface declarations */ extern char *XR_malloc(); extern char *XR_SPrintF(); typedef (*procpointer)(); static (*lrh_command_ptr)() = (procpointer)XR_lrh_Command; static (*Comment_ptr)() = (procpointer)XR_Comment_Command; static (*RequireFrom_ptr)() = (procpointer)XR_RequireFrom_Command; static (*ORequireFrom_ptr)() = (procpointer)XR_ORequireFrom_Command; static (*DRequireFrom_ptr)() = (procpointer)XR_DRequireFrom_Command; static (*LoadFrom_ptr)() = (procpointer)XR_LoadFrom_Command; static (*RunFrom_ptr)() = (procpointer)XR_RunFrom_Command; static (*ReleaseLocation_ptr)() = (procpointer)XR_ReleaseLocation_Command; /* fatal error */ static int FatalVersionError(s) char *s; { (void)XR_FPrintF(stdout, "Error - all UNames must have a %s.\n", s); exit(1); } /* string utilities */ static char *LowerCase(s) char *s; { int length = strlen(s); char *scratch = (char *)XR_malloc((unsigned)(length+1)); int i; int c; scratch[length] = NULL; for ( i = 0; i < length; i++ ) { c = s[i]; scratch[i] = isupper(c) ? tolower(c) : c; }; return(scratch); }; static char *LowerCaseAndDot(s) char *s; { int length = strlen(s); char *scratch = (char *)XR_malloc((unsigned)(length+1)); int i; int c; scratch[length] = NULL; for ( i = 0; i < length; i++ ) { c = s[i]; c = isupper(c) ? tolower(c) : c; scratch[i] = (c == CH_DOT) ? CH_UNDERSCORE : c; }; return(scratch); }; static void StripCR(s) char *s; { int last = strlen(s) - 1; if ( last < 0) { return; }; if ( s[last] == CH_CR ) { s[last] = NULL; }; } static void StripSlash(s) char *s; { int last = strlen(s) - 1; if ( last < 0) { return; }; if ( s[last] == CH_SLASH ) { s[last] = NULL; }; } /* stuff */ static int ParseBaseAndVersion(base) char *base; { int version; /* result */ char *temp = strchr(base, CH_TILDE); if (temp == NULL) { /* NO version */ version = 0; } else { /* version exists */ char *versionPlus = temp+1; temp = temp - 1; if ( temp[0] != CH_DOT ) { FatalVersionError("version"); }; temp[0] = NULL; /* delete the ".~" */ temp[1] = NULL; temp = strchr(versionPlus, CH_TILDE); if ( temp == NULL ) { FatalVersionError("version"); }; temp[0] = NULL; version = atoi(versionPlus); if ( version == 0 ) { FatalVersionError("non-zero version"); }; } return(version); } static int ParseUName(name, pathPrefix, base) char *name, *pathPrefix, *base; { int version; /* result */ char pattern[1024]; char *temp, *basePlus; (void)strcpy(pattern, name); /* first get the path prefix */ if ( pattern[0] != CH_SLASH ) { FatalVersionError("leading slash(/)"); }; temp = strrchr(pattern, CH_SLASH); if ( temp == NULL ) { FatalVersionError("directory part"); }; basePlus = temp + 1; temp[0] = NULL; (void)strcpy(pathPrefix, pattern); /* next get base */ (void)strcpy(base, basePlus); version = ParseBaseAndVersion(base); return(version); } static void GetPattern(pattern, pathPrefix, base) char *pattern, *pathPrefix, *base; { (void)strcpy(pattern, pathPrefix); (void)strcat(pattern, STR_SLASH); (void)strcat(pattern, base); } static void ParseDirectoryAndFileName(directory, fileNamePrefix, pattern) char *directory, *fileNamePrefix, *pattern; { char *temp; (void)strcpy(directory, pattern); temp = strrchr(directory, CH_SLASH); (void)strcpy(fileNamePrefix, temp+1); temp[0] = NULL; } static int GetVersionFromName(name) char *name; { int version; /* result */ char buf[1024]; (void)strcpy(buf, name); version = ParseBaseAndVersion(buf); return(version); } /* File System & Directory access */ DIR *OpenDir(name) char *name; { register DIR *dirp; /* result */ register int fd; struct stat sb; if ( ( fd = XR_Open(name, 0) ) == -1 ) { return(NULL); }; if ( XR_FStat(fd, &sb) == -1 ) { (void) XR_Close(fd); return(NULL); } if ( ( sb.st_mode & S_IFMT ) != S_IFDIR ) { XR_SetErrno(ENOTDIR); (void) XR_Close(fd); return(NULL); } if ( ((dirp = (DIR *)XR_malloc(sizeof(DIR))) == NULL ) || ((dirp->dd_buf =XR_malloc((unsigned)sb.st_blksize)) == NULL)) { if (dirp) free((char *)dirp); (void) XR_Close(fd); return(NULL); } dirp->dd_fd = fd; dirp->dd_loc = 0; dirp->dd_size = 0; dirp->dd_bsize = sb.st_blksize; dirp->dd_off = 0; return(dirp); } int CloseDir(dirp) DIR *dirp; { int fd; fd = dirp->dd_fd; dirp->dd_fd = -1; dirp->dd_loc = 0; (void)free(dirp->dd_buf); (void)free((char *)dirp); return(XR_Close(fd)); } struct dirent *ReadDir(dirp) DIR *dirp; { struct dirent *dp; int saveloc = 0; next: if (dirp->dd_size != 0) { dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc]; saveloc = dirp->dd_loc; /* save for possible EOF */ dirp->dd_loc += dp->d_reclen; } if (dirp->dd_loc >= dirp->dd_size) dirp->dd_loc = dirp->dd_size = 0; if ( dirp->dd_size == 0 /* refill buffer */ && ( (dirp->dd_size = XR_GetDEnts(dirp->dd_fd, dirp->dd_buf, dirp->dd_bsize)) <= 0 ) ) { if ( dirp->dd_size == 0 ) { dirp->dd_loc = saveloc; }; /* This means EOF, so save for telldir */ return(NULL); /* error or EOF */ } dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc]; if ( dp->d_reclen <= 0 ) { return(NULL); }; if ( dp->d_fileno == 0 ) { goto next; }; dirp->dd_off = dp->d_off; return(dp); } /* more stuff */ static int GetHighestVersion(pattern) char *pattern; { int highestVersion = -1; /* result */ char directory[1024]; char fileNamePrefix[100]; int len; int version = -1; DIR *dirp; struct dirent *dp; ParseDirectoryAndFileName(directory, fileNamePrefix, pattern); dirp = OpenDir(directory); if (dirp == NULL) return(highestVersion); len = strlen(fileNamePrefix); for (dp = ReadDir(dirp); dp != NULL; dp = ReadDir(dirp)) { if ( ! strncmp(dp->d_name, fileNamePrefix, len) ) { version = GetVersionFromName(dp->d_name); if ( version > highestVersion ) { highestVersion = version; }; }; }; (void)CloseDir (dirp); return(highestVersion); } static void MakeUName(pattern, pathPrefix, base, version) char *pattern, *pathPrefix, *base; int version; { char buf[10]; (void)strcpy(pattern, pathPrefix); (void)strcat(pattern, STR_SLASH); (void)strcat(pattern, base); (void)strcat(pattern, STR_DOT_TILDE); (void)XR_SPrintF(buf, "%d", version); (void)strcat(pattern, buf); (void)strcat(pattern, STR_TILDE); } static void ExpandFileVersion(oldfile, newfile) char *oldfile, *newfile; { char pathPrefix[1024]; char base[255]; int version; (void)ParseUName(oldfile, pathPrefix, base); GetPattern(newfile, pathPrefix, base); version = GetHighestVersion(newfile); MakeUName(newfile, pathPrefix, base, version); } extern void getnewfile(oldfile, newfile) char *oldfile, *newfile; { /* backward compat */ ExpandFileVersion(oldfile, newfile); }; void XR_Comment_Command(command) char *command; { }; void XR_RequireFrom_Command(command) char *command; { char *releasename; char *releasevar; char *pkg; char *module; char *path; char *directory; char *file; char *cmd; char *fullname; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); pkg = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); module = strtok((char *)NULL, STR_PUNCTUATION); file = LowerCase(module); directory = XR_getenv(releasevar); StripSlash(directory); path = (char *)XR_malloc((unsigned)(strlen(directory) + strlen(pkg) + strlen(file) + 20)); (void)XR_SPrintF(path, "%s/%s/sun4/%s.c2c.o", directory, pkg, file); fullname = (char *)XR_malloc((unsigned)(strlen(path) + 20)); ExpandFileVersion(path, fullname); cmd = (char *)XR_malloc((unsigned)(strlen(fullname) + strlen(module) + 20)); (void)XR_SPrintF(cmd, "LoadAndRun %s %s \n", fullname, module); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, pkg: {%s} module: {%s}]\n", releasename, pkg, module); (void)XR_FPrintF(stdout, " %s", cmd); XR_SetCurrentCommand(cmd); XR_loadAndRun_command(cmd); (void)free(scratch); }; void XR_DRequireFrom_Command(command) char *command; { char *releasename; char *releasevar; char *pkg; char *module; char *path; char *directory; char *file; char *cmd; char *fullname; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); pkg = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); module = strtok((char *)NULL, STR_PUNCTUATION); file = LowerCase(module); directory = XR_getenv(releasevar); StripSlash(directory); path = (char *)XR_malloc((unsigned)(strlen(directory) + strlen(pkg) + strlen(file) + 20)); (void)XR_SPrintF(path, "%s/%s/sun4/%s.c2c.o", directory, pkg, file); fullname = (char *)XR_malloc((unsigned)(strlen(path) + 20)); ExpandFileVersion(path, fullname); cmd = (char *)XR_malloc((unsigned)(strlen(fullname) + strlen(module) + 20)); (void)XR_SPrintF(cmd, "LoadAndRun %s %s -d \n", fullname, module); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, pkg: {%s} module: {%s}]\n", releasename, pkg, module); (void)XR_FPrintF(stdout, " %s", cmd); XR_SetCurrentCommand(cmd); XR_loadAndRun_command(cmd); (void)free(scratch); }; void XR_ORequireFrom_Command(command) char *command; { char *releasename; char *releasevar; char *pkg; char *module; char *path; char *directory; char *file; char *cmd; char *fullname; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); pkg = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); module = strtok((char *)NULL, STR_PUNCTUATION); file = LowerCase(module); directory = XR_getenv(releasevar); StripSlash(directory); path = (char *)XR_malloc((unsigned)(strlen(directory) + strlen(pkg) + strlen(file) + 20)); (void)XR_SPrintF(path, "%s/%s/sun4-o3/%s.c2c.o", directory, pkg, file); fullname = (char *)XR_malloc((unsigned)(strlen(path) + 20)); ExpandFileVersion(path, fullname); cmd = (char *)XR_malloc((unsigned)(strlen(fullname) + strlen(module) + 20)); (void)XR_SPrintF(cmd, "LoadAndRun %s %s -d \n", fullname, module); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, pkg: {%s} module: {%s}]\n", releasename, pkg, module); (void)XR_FPrintF(stdout, " %s", cmd); XR_SetCurrentCommand(cmd); XR_loadAndRun_command(cmd); (void)free(scratch); }; void XR_LoadFrom_Command(command) char *command; { char *releasename; char *releasevar; char *pkg; char *module; char *path; char *directory; char *file; char *cmd; char *fullname; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); pkg = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); module = strtok((char *)NULL, STR_PUNCTUATION); file = LowerCase(module); directory = XR_getenv(releasevar); StripSlash(directory); path = (char *)XR_malloc((unsigned)(strlen(directory) + strlen(pkg) + strlen(file) + 20)); (void)XR_SPrintF(path, "%s/%s/sun4/%s.c2c.o", directory, pkg, file); fullname = (char *)XR_malloc((unsigned)(strlen(path) + 20)); ExpandFileVersion(path, fullname); cmd = (char *)XR_malloc((unsigned)(strlen(fullname) + strlen(module) + 20)); (void)XR_SPrintF(cmd, "Load %s %s \n", fullname, module); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, pkg: {%s} module: {%s}]\n", releasename, pkg, module); (void)XR_FPrintF(stdout, " %s", cmd); XR_SetCurrentCommand(cmd); XR_load_command(cmd); (void)free(scratch); }; void XR_RunFrom_Command(command) char *command; { char *releasename; char *releasevar; char *pkg; char *module; char *path; char *directory; char *file; char *cmd; char *fullname; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); pkg = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); module = strtok((char *)NULL, STR_PUNCTUATION); file = LowerCase(module); directory = XR_getenv(releasevar); StripSlash(directory); path = (char *)XR_malloc((unsigned)(strlen(directory) + strlen(pkg) + strlen(file) + 20)); (void)XR_SPrintF(path, "%s/%s/sun4/%s.c2c.o", directory, pkg, file); fullname = (char *)XR_malloc((unsigned)(strlen(path) + 20)); ExpandFileVersion(path, fullname); cmd = (char *)XR_malloc((unsigned)(strlen(fullname) + strlen(module) + 20)); (void)XR_SPrintF(cmd, "Run %s %s \n", fullname, module); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, pkg: {%s} module: {%s}]\n", releasename, pkg, module); (void)XR_FPrintF(stdout, " %s", cmd); XR_SetCurrentCommand(cmd); XR_run_command(cmd); (void)free(scratch); }; void XR_ReleaseLocation_Command(command) char *command; { char *releasename; char *releasevar; char *directory; char *scratch = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(scratch, command); (void)strtok(scratch, STR_PUNCTUATION); /* skip the command name */ releasename = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); releasevar = LowerCaseAndDot(releasename); directory = LowerCase(strtok((char *)NULL, STR_PUNCTUATION)); XR_setenv(releasevar, directory, 1); if ( 0 == 1 ) (void)XR_FPrintF(stdout, "[release: {%s}, directory: {%s}]\n", releasename, directory); (void)free(scratch); }; void XR_lrh_Command(command) char *command; { char *cmd_rememberer; char *rest, *oldfile; char *new = (char *)XR_malloc((unsigned)(strlen(command) + 100)); char *newcommand = (char *)XR_malloc((unsigned)(strlen(command) + 100)); (void)strcpy(new, command); /* discard the lrh */ (void)strtok(new, STR_WHITESPACE); oldfile = strtok((char *)NULL, STR_WHITESPACE); rest = strtok((char *)NULL, STR_NULL); StripCR(oldfile); ExpandFileVersion(oldfile, new); (void)strcpy(newcommand, "lr "); (void)strcat(newcommand, new); (void)strcat(newcommand, STR_BLANK); if ( rest != NULL ) { (void)strcat(newcommand, STR_BLANK); (void)strcat(newcommand, rest); } cmd_rememberer = (char *)XR_malloc((unsigned)(strlen(newcommand) + 1)); (void)strcpy(cmd_rememberer, newcommand); if ( XR_load_command(newcommand) ) { XR_run_command(cmd_rememberer); }; (void)free(new); } void XR_install_LoaderUtilsImpl() { /* PRE-start trap */ }; void XR_run_LoaderUtilsImpl() { /* start trap */ <> <> XR_register("lrh", &lrh_command_ptr, "Like lr, but use !h", 0); XR_register("#", &Comment_ptr, "the obvious noop", 0); XR_register("--", &Comment_ptr, "the obvious noop", 0); XR_register("Comment", &Comment_ptr, "the obvious noop", 0); XR_register("RequireFrom", &RequireFrom_ptr, "LoadAndRun(release, pkg, module)", 0); XR_register("DRequireFrom", &DRequireFrom_ptr, "LoadAndRun(release, pkg, module) -d", 0); XR_register("ORequireFrom", &ORequireFrom_ptr, "LoadAndRunOptimizedVersion(release, pkg, module) -d", 0); XR_register("LoadFrom", &LoadFrom_ptr, "Load(release, pkg, module)", 0); XR_register("RunFrom", &RunFrom_ptr, "Run(release, pkg, module)", 0); XR_register("ReleaseLocation", &ReleaseLocation_ptr, "setenv ReleaseLocation (release)", 0); } /* eof */