void Sanitize_Repository_Name (char **repository) { size_t len; assert (repository && *repository); strip_trailing_slashes (*repository); len = strlen (*repository); if (len >= 2 && (*repository)[len - 1] == '.' && ISDIRSEP ((*repository)[len - 2])) { (*repository)[len - 2] = '\0'; } /* If we're proxying, makes sure we always use the alias name to communicate */ if(proxy_active && strlen(*repository)>strlen(current_parsed_root->original) && !strncmp(*repository,current_parsed_root->original,strlen(current_parsed_root->original)) && ISDIRSEP((*repository)[strlen(current_parsed_root->original)])) { char *newrep = (char*)xmalloc(strlen(current_parsed_root->directory) + strlen(*repository)); sprintf(newrep,"%s%s",current_parsed_root->directory,(*repository)+strlen(current_parsed_root->original)); xfree(*repository); *repository = newrep; } }
int isview( /* is this a view string? */ char *s ) { static char *altname[]={NULL,VIEWSTR,"rpict","rview","rvu","rpiece","pinterp",NULL}; extern char *progname; char *cp; char **an; /* add program name to list */ if (altname[0] == NULL) { for (cp = progname; *cp; cp++) ; while (cp > progname && !ISDIRSEP(cp[-1])) cp--; altname[0] = cp; } /* skip leading path */ cp = s; while (*cp && *cp != ' ') cp++; while (cp > s && !ISDIRSEP(cp[-1])) cp--; for (an = altname; *an != NULL; an++) if (!strncmp(*an, cp, strlen(*an))) return(1); return(0); }
/* Remote server might be anything, so we have to deal with all types of path here */ int isabsolute_remote (const char *filename) { return (ISDIRSEP (filename[0]) || (filename[0] != '\0' && filename[1] == ':' && ISDIRSEP (filename[2]))); }
bool _ScanDir(CStr path, int mask, CStr body, qCtx *ctx, qStr *out, DIRSTATE &st) { BOOL bMore; HANDLE hFind; BOOL showdot = false; // truncate trailing slashes char *b = path.GetBuffer(); if (!b || !*b) return false; char *p = path+path.Length() - 1; while (p >= b && ISDIRSEP(*p)) --p; if (p-b+1 > 0) { if (*p == ':') { showdot = true; if (!ISDIRSEP(p[1])) { path << '.'; b = path.GetBuffer(); p = path+path.Length() - 1; } else ++p; } st.path = path; // truncate path to parent while (p >= b && !ISPATHSEP(*p)) --p; if (p >= b) { st.path.Grow(p-b+1); } else { st.path.Grow(0); } } else { st.path = path; } // read all entries in the directory WIN32_FIND_DATA *r = &st.data; hFind = FindFirstFile(path, r); bMore = (hFind != (HANDLE) -1); while (bMore &&!st.bquit) { if ((mask & r->dwFileAttributes) && !(r->cFileName[0]=='.'&&r->cFileName[1]=='\0') ) { ctx->Parse(body, out); } else if (showdot && r->cFileName[0]=='.'&&r->cFileName[1]=='\0') { ctx->Parse(body, out); } bMore = FindNextFile(hFind, r); } FindClose(hFind); return true; } // dir_scan
static char * set_current_prefix (const char *ModuleName) { LPTSTR curr_prefix_arg, q, lpFilePart; DWORD len; int nDIRSEP = 0; if (curr_prefix) free (curr_prefix); curr_prefix_arg = malloc (MAX_PATH * sizeof (TCHAR)); if (!curr_prefix_arg) { set_werrno; curr_prefix = NULL; curr_prefix_len = 0; return NULL; } if (ModuleName) { // printf ("ModuleName: %s\n", ModuleName); len = SearchPath (NULL, ModuleName, ".DLL", MAX_PATH, curr_prefix_arg, &lpFilePart); if (len) { // printf ("ModulePath: %s\n", curr_prefix_arg); // printf ("FilePart: %s\n", lpFilePart); } } if (!ModuleName || !len) { len = GetModuleFileName (NULL, curr_prefix_arg, MAX_PATH); if (!len) { set_werrno; curr_prefix = NULL; curr_prefix_len = 0; return NULL; } } // strncpy (curr_prefix_arg, ModuleName, MAX_PATH); // printf ("curr_prefix_arg: %s\n", curr_prefix_arg); win2posixpath (curr_prefix_arg, curr_prefix_arg); curr_prefix = curr_prefix_arg; q = curr_prefix_arg + len - 1; /* strip name of executable and its directory */ while (!ISDIRSEP (*q) && (q > curr_prefix_arg) && nDIRSEP < 2) { q--; if (ISDIRSEP (*q)) { *q = '\0'; nDIRSEP++; } } curr_prefix_len = q - curr_prefix_arg; // printf ("curr_prefix: %s\n", curr_prefix); // printf ("curr_prefix_len: %d\n", curr_prefix_len); return curr_prefix; }
/* Sets the original and the current installation prefix of this module. Relocation simply replaces a pathname starting with the original prefix by the corresponding pathname with the current prefix instead. Both prefixes should be directory names without trailing slash (i.e. use "" instead of "/"). */ static char * set_orig_prefix (const char *orig_prefix_arg) { char *memory; // printf ("orig_prefix_arg: %s\n", orig_prefix_arg); if (!orig_prefix_arg) { orig_prefix = NULL; orig_prefix_len = 0; return NULL; } if (orig_prefix) free (orig_prefix); memory = canonicalize_file_name (orig_prefix_arg); // printf ("memory: %s\n", memory); // memory = (char *) malloc (orig_prefix_len + 1); if (!memory) { set_werrno; orig_prefix = NULL; orig_prefix_len = 0; return NULL; } win2unixpath (memory); // win2posixpath (orig_prefix_arg, memory); orig_prefix = memory; orig_prefix_len = strlen (orig_prefix); // printf ("orig_prefix: %s\n", orig_prefix); if (ISDIRSEP (orig_prefix[orig_prefix_len-1])) { orig_prefix[orig_prefix_len-1] = '\0'; orig_prefix_len--; } // printf ("orig_prefix: %s\n", orig_prefix); // printf ("orig_prefix_len: %d\n", orig_prefix_len); return orig_prefix; }
/* * Make a path to the argument directory, printing a message if something * goes wrong. */ void make_directories (const char *name) { char *cp; char *dir; if (noexec) return; if (CVS_MKDIR (name, 0777) == 0 || errno == EEXIST) return; if (errno != ENOENT) { error (0, errno, "cannot make path to %s", fn_root(name)); return; } dir = xstrdup(name); for(cp=dir+strlen(dir); cp>dir && !ISDIRSEP(*cp); --cp) ; if(cp==dir) { xfree(dir); return; } *cp = '\0'; make_directories (dir); *cp++ = '/'; if (*cp == '\0') { xfree(dir); return; } xfree(dir); CVS_MKDIR (name, 0777); }
/* FIXME: Should be using ISDIRSEP, last_component, or some other mechanism which is more general than just looking at slashes, particularly for the client.c caller. The server.c caller might want something different, so be careful. */ int pathname_levels (const char *path) { const char *p; const char *q; #ifdef _WIN32 const char *q1,*q2; #endif int level; int max_level; max_level = 0; p = path; level = 0; do { #ifdef _WIN32 q1 = strchr (p, '/'); q2 = strchr (p, '\\'); if(q1!=NULL && (q1<q2)) q=q1; else if(q1==NULL && (q1>q2)) q=q2; else q=q1; /* Probably NULL */ #else q = strchr (p, '/'); #endif if (q != NULL) ++q; if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || ISDIRSEP(p[2]))) { --level; if (-level > max_level) max_level = -level; } else if (p[0] == '\0' || ISDIRSEP(p[0]) || (p[0] == '.' && (p[1] == '\0' || ISDIRSEP(p[1])))) ; else ++level; p = q; } while (p != NULL); return max_level; }
/* Read a directory entry from DIRP. */ struct dirent64 * __readdir64 (DIR *dirp) { WIN32_FIND_DATA dir_find_data; DIRdata *ddp = (DIRdata *) dirp->data; struct stat64 sb; if (dirp == NULL) { __set_errno (EBADF); return NULL; } /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */ if (dirp->fd == INVALID_DIRFD) { char filename[MAX_PATH + 3]; int len; strcpy (filename, ddp->dirname); len = strlen (filename) - 1; if (!ISDIRSEP (filename[len])) strcat (filename, "\\"); strcat (filename, "*"); dirp->fd = (int) FindFirstFile (filename, &dir_find_data); if (dirp->fd == INVALID_HANDLE_VALUE) { dirp->fd = INVALID_DIRFD; set_werrno; return NULL; } } else { if (!FindNextFile ((HANDLE) dirp->fd, &dir_find_data)) { if (!(GetLastError () == ERROR_NO_MORE_FILES)) set_werrno; return NULL; } } __libc_lock_lock (dirp->lock); strncpy (ddp->DIRdir.d_name, ddp->dirname, MAX_PATH); strncat (ddp->DIRdir.d_name, "\\", MAX_PATH); strncat (ddp->DIRdir.d_name, dir_find_data.cFileName, MAX_PATH); if (lstat64 (ddp->DIRdir.d_name, &sb)) { set_werrno; return NULL; } ddp->DIRdir.d_type = IFTODT(sb.st_mode); ddp->DIRdir.d_namlen = strlen (dir_find_data.cFileName); ddp->DIRdir.d_reclen = sizeof (struct dirent64); ddp->DIRdir.d_ino = sb.st_ino; strncpy (ddp->DIRdir.d_name, dir_find_data.cFileName, MAX_PATH); __libc_lock_unlock (dirp->lock); ++dirp->filepos; errno = 0; return &ddp->DIRdir; }
/* * Make a path to the argument directory, printing a message if something * goes wrong. */ void CFileAccess::_tmake_directories(const char *name, const TCHAR *fn) { DWORD fa; TCHAR *dir; TCHAR *cp; fa = GetFileAttributes(fn); if(fa!=0xFFFFFFFF) { if(!(fa&FILE_ATTRIBUTE_DIRECTORY)) CServerIo::error (0, 0, "%s already exists but is not a directory", name); else { return; } } if (!CreateDirectory(fn,NULL)) { DWORD dwErr = GetLastError(); if(dwErr!=ERROR_PATH_NOT_FOUND) { _dosmaperr(dwErr); CServerIo::error (0, errno, "cannot make directory %s", name); return; } } else return; dir = _tcsdup(fn); for(cp=dir+_tcslen(dir);cp>dir && !ISDIRSEP(*cp); --cp) ; if(cp==dir) { free(dir); return; } *cp = '\0'; _tmake_directories (name,dir); *cp++ = '/'; if (*cp == '\0') { free(dir); return; } if (!CreateDirectory(dir,NULL)) { _dosmaperr(GetLastError()); CServerIo::error (0, errno, "cannot make directory %s", name); free(dir); return; } free(dir); }
/* * Return a pointer to the repository name relative to CVSROOT from a * possibly fully qualified repository */ const char *Short_Repository (const char *repository) { if (repository == NULL) return (NULL); /* If repository matches CVSroot at the beginning, strip off CVSroot */ /* And skip leading '/' in rep, in case CVSroot ended with '/'. */ if (fnncmp (current_parsed_root->directory, repository, strlen (current_parsed_root->directory)) == 0) { const char *rep = repository + strlen (current_parsed_root->directory); return (ISDIRSEP(*rep)) ? rep+1 : rep; } else return (repository); }
void EvalDirMakePath(const void *mode, qCtx *ctx, qStr *out, qArgAry *args) { VALID_ARGC("mkpath", 1, 1); char * path = (*args)[0].SafeP(); if (!path) return; char *p = path; while (*p) { while (*p && !ISDIRSEP(*p)) { ++p; } CStr tmp(path, p-path); if (!tmp.IsEmpty()) mkdir(tmp, 0777); ++p; } }
/* * jt_err() * * Prints error message to standard error and exits with a failure exit code. * * progname Name of program. Used to prefix error message. * fmt Format of error message, cf. printf(). */ void jt_err(char *progname, char *fmt, ...) { char *cp; va_list vlist; for (cp = progname; *cp != '\0'; cp++) { if (ISDIRSEP(*cp) && *(cp + 1) != '\0') progname = cp + 1; } fprintf(stderr, "%s: ", progname); va_start(vlist, fmt); vfprintf(stderr, fmt, vlist); va_end(vlist); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
core_getpath /* wrapped below: expand fname, return full path */ #else char * getpath /* expand fname, return full path */ #endif ( char *fname, char *searchpath, int mode ) { static char pname[PATH_MAX]; char uname[512]; char *cp; int i; if (fname == NULL) { return(NULL); } pname[0] = '\0'; /* check for full specification */ if (ISABS(fname)) { /* absolute path */ strncpy(pname, fname, sizeof(pname)-1); } else { switch (*fname) { case '.': /* relative to cwd */ strncpy(pname, fname, sizeof(pname)-1); break; case '~': /* relative to home directory */ fname++; cp = uname; for (i=0;i<sizeof(uname)&&*fname!='\0'&&!ISDIRSEP(*fname);i++) *cp++ = *fname++; *cp = '\0'; cp = gethomedir(uname, pname, sizeof(pname)); if(cp == NULL) return NULL; strncat(pname, fname, sizeof(pname)-strlen(pname)-1); break; } } if (pname[0]) /* got it, check access if search requested */ return(searchpath==NULL||access(pname,mode)==0 ? pname : NULL); if (searchpath == NULL) { /* don't search */ strncpy(pname, fname, sizeof(pname)-1); return(pname); } /* check search path */ do { cp = pname; while (*searchpath && (*cp = *searchpath++) != PATHSEP) { cp++; } if (cp > pname && !ISDIRSEP(cp[-1])) { *cp++ = DIRSEP; } strncpy(cp, fname, sizeof(pname)-strlen(pname)-1); if (access(pname, mode) == 0) /* file accessable? */ return(pname); } while (*searchpath); /* not found */ return(NULL); }
/* * Implement the recursive policies on the local directory. This may be * called directly, or may be called by start_recursion */ static int do_recursion (struct recursion_frame *frame, int top_level) { int err = 0; int dodoneproc = 1; char *srepository; List *entries = NULL; int should_readlock; int process_this_directory = 1; /* do nothing if told */ if (frame->flags == R_SKIP_ALL) return (0); should_readlock = noexec ? 0 : frame->readlock; /* Check the value in CVSADM_ROOT and see if it's in the list. If not, add it to our lists of CVS/Root directories and do not process the files in this directory. Otherwise, continue as usual. THIS_ROOT might be NULL if we're doing an initial checkout -- check before using it. The default should be that we process a directory's contents and only skip those contents if a CVS/Root file exists. If we're running the server, we want to process all directories, since we're guaranteed to have only one CVSROOT -- our own. */ /* If -d was specified, it should override CVS/Root. In the single-repository case, it is long-standing CVS behavior and makes sense - the user might want another access method, another server (which mounts the same repository), &c. In the multiple-repository case, -d overrides all CVS/Root files. That is the only plausible generalization I can think of. */ if(!(frame->which&W_FAKE) && CVSroot_cmdline == NULL && ! server_active) { char *this_root = Name_Root ((char *) NULL, update_dir); if (this_root != NULL) { if (findnode_fn (root_directories, this_root) == NULL) { /* Add it to our list. */ Node *n = getnode (); n->type = NT_UNKNOWN; n->key = xstrdup (this_root); if (addnode (root_directories, n)) error (1, 0, "cannot add new CVSROOT %s", this_root); } process_this_directory = (fncmp (current_parsed_root->original, this_root) == 0); xfree (this_root); } } /* * Fill in repository with the current repository */ if (frame->which & W_LOCAL) { if (isdir (CVSADM)) repository = Name_Repository ((char *) NULL, update_dir); else repository = NULL; } else { if(update_repos) /* May have been preloaded by checkout */ repository = xstrdup(update_repos); else { repository = (char*)xmalloc(strlen(current_parsed_root->directory)+strlen(update_dir)+10); sprintf(repository,"%s/%s",current_parsed_root->directory,update_dir); } } if(repository && ISDIRSEP(repository[strlen(repository)-1])) repository[strlen(repository)-1]='\0'; srepository = repository; /* remember what to free */ if(repository && !current_parsed_root->isremote) { mapped_repository = map_repository(repository); } else { mapped_repository=xstrdup(repository); } xfree(last_repository); last_repository = xstrdup(mapped_repository); /* * Do we have access to this directory? */ /* Note that for a recursion this is done already in do_dir_proc... */ if(top_level) { if(repository && !current_parsed_root->isremote) { const char *tag; const char *message; const char *v_msg; ParseTag(&tag, NULL, NULL, NULL); if (! verify_access(frame->permproc, mapped_repository, NULL, update_dir,frame->tag?frame->tag:tag,&message, &v_msg)) { if(tag) error (0, 0, "User '%s' cannot %s %s on tag/branch %s", CVS_Username, v_msg, fn_root(repository), tag); else error (0, 0, "User '%s' cannot %s %s", CVS_Username, v_msg, fn_root(repository)); if(message) error (0, 0, "%s", message); return (1); } xfree(tag); fileattr_startdir (mapped_repository); } } /* * The filesdoneproc needs to be called for each directory where files * processed, or each directory that is processed by a call where no * directories were passed in. In fact, the only time we don't want to * call back the filesdoneproc is when we are processing directories that * were passed in on the command line (or in the special case of `.' when * we were called with no args */ if (dirlist != NULL && filelist == NULL) dodoneproc = 0; /* * If filelist or dirlist is already set, we don't look again. Otherwise, * find the files and directories */ if (filelist == NULL && dirlist == NULL) { /* both lists were NULL, so start from scratch */ if (frame->fileproc != NULL && frame->flags != R_SKIP_FILES) { int lwhich = frame->which; /* In the !(which & W_LOCAL) case, we filled in repository earlier in the function. In the (which & W_LOCAL) case, the Find_Names function is going to look through the Entries file. If we do not have a repository, that does not make sense, so we insist upon having a repository at this point. Name_Repository will give a reasonable error message. */ if (repository == NULL) repository = Name_Repository ((char *) NULL, update_dir); else if(mapped_repository == NULL) mapped_repository = map_repository(repository); /* find the files and fill in entries if appropriate */ if (process_this_directory) { filelist = Find_Names (mapped_repository, lwhich, frame->aflag, &entries, repository); if (filelist == NULL) { error (0, 0, "skipping directory %s", update_dir); /* Note that Find_Directories and the filesdoneproc in particular would do bad things ("? foo.c" in the case of some filesdoneproc's). */ goto skip_directory; } } } if (frame->flags == R_SKIP_DIRS && !(frame->which&W_LOCAL) && nonrecursive_module(repository)) frame->flags = R_SKIP_DIRS; /* find sub-directories if we will recurse */ if (frame->flags != R_SKIP_DIRS) dirlist = Find_Directories ( process_this_directory ? mapped_repository : NULL, frame->which, entries, repository); } else { /* something was passed on the command line */ if (filelist != NULL && frame->fileproc != NULL) { /* we will process files, so pre-parse entries */ if (frame->which & W_LOCAL) entries = Entries_Open (frame->aflag, NULL); } } /* process the files (if any) */ if (process_this_directory && filelist != NULL && frame->fileproc) { struct file_info finfo_struct; struct frame_and_file frfile; /* read lock it if necessary */ if (should_readlock && mapped_repository && Reader_Lock (mapped_repository) != 0) error (1, 0, "read lock failed - giving up"); /* For the server, we handle notifications in a completely different place (server_notify). For local, we can't do them here--we don't have writelocks in place, and there is no way to get writelocks here. */ if (current_parsed_root->isremote) client_notify_check (repository, update_dir); finfo_struct.repository = mapped_repository; finfo_struct.update_dir = update_dir; finfo_struct.entries = entries; finfo_struct.virtual_repository = repository; /* do_file_proc will fill in finfo_struct.file. */ frfile.finfo = &finfo_struct; frfile.frame = frame; /* process the files */ err += walklist (filelist, do_file_proc, &frfile); /* unlock it */ if (should_readlock) Lock_Cleanup_Directory(); /* clean up */ if (filelist) dellist (&filelist); } /* call-back files done proc (if any) */ if (process_this_directory && dodoneproc && frame->filesdoneproc != NULL) { err = frame->filesdoneproc (frame->callerdat, err, (char*)mapped_repository, (char*)(update_dir[0] ? update_dir : "."), entries); } skip_directory: if(repository && !current_parsed_root->isremote) { fileattr_write (); fileattr_free (); } /* process the directories (if necessary) */ if (dirlist != NULL) { // BUGME!!! /* for some reason this code path is not entered some times when it SHOULD be, eg: after a rename! This means the .direcrory_history file is not created !!!! */ struct frame_and_entries frent; frent.frame = frame; frent.entries = entries; err += walklist (dirlist, do_dir_proc, (void *) &frent); } if (dirlist) dellist (&dirlist); if (entries) { Entries_Close (entries); entries = NULL; } /* free the saved copy of the pointer if necessary */ xfree (srepository); xfree (mapped_repository); repository = NULL; return (err); }
/* * Finds all the subdirectories of the argument dir and adds them to * the specified list. Sub-directories without a CVS administration * directory are optionally ignored. If ENTRIES is not NULL, all * files on the list are ignored. Returns 0 for success or 1 on * error, in which case errno is set to indicate the error. */ static int find_dirs (const char *dir, List *list, int checkadm, List *entries, const char *regex) { Node *p; char *tmp = NULL; size_t tmp_size = 0; struct dirent *dp; DIR *dirp; int skip_emptydir = 0; /* First figure out whether we need to skip directories named Emptydir. Except in the CVSNULLREPOS case, Emptydir is just a normal directory name. */ if (isabsolute (dir) && fnncmp (dir, current_parsed_root->directory, strlen (current_parsed_root->directory)) == 0 && ISDIRSEP (dir[strlen (current_parsed_root->directory)]) && fncmp (dir + strlen (current_parsed_root->directory) + 1, CVSROOTADM) == 0) skip_emptydir = 1; /* set up to read the dir */ if ((dirp = opendir (dir)) == NULL) return (1); /* read the dir, grabbing sub-dirs */ errno = 0; while ((dp = readdir (dirp)) != NULL) { if (fncmp (dp->d_name, ".") == 0 || fncmp (dp->d_name, "..") == 0 || fncmp (dp->d_name, CVSATTIC) == 0 || fncmp (dp->d_name, CVSLCK) == 0 || fncmp (dp->d_name, CVSREP) == 0 || fncmp (dp->d_name, CVSDUMMY) == 0) goto do_it_again; /* findnode() is going to be significantly faster than stat() because it involves no system calls. That is why we bother with the entries argument, and why we check this first. */ if (entries != NULL && findnode_fn (entries, dp->d_name) != NULL) goto do_it_again; if (skip_emptydir && fncmp (dp->d_name, CVSNULLREPOS) == 0) goto do_it_again; /* don't bother stating ,v files */ if (CVS_FNMATCH (RCSPAT, dp->d_name, CVS_CASEFOLD) == 0) goto do_it_again; expand_string (&tmp, &tmp_size, strlen (dir) + strlen (dp->d_name) + 10); sprintf (tmp, "%s/%s", dir, dp->d_name); if (!isdir (tmp)) goto do_it_again; /* check for administration directories (if needed) */ if (checkadm) { /* blow off symbolic links to dirs in local dir */ /* Note that we only get here if we already set tmp above. */ if (islink (tmp)) goto do_it_again; /* check for new style */ expand_string (&tmp, &tmp_size, (strlen (dir) + strlen (dp->d_name) + sizeof (CVSADM) + 10)); (void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM); if (!isdir (tmp)) goto do_it_again; } /* If there's a regex, test against the name with '/' on the end to signify a directory */ if(regex) { strcpy(tmp,dp->d_name); strcat(tmp,"/"); if(!regex_filename_match(regex,tmp)) goto do_it_again; } /* put it in the list */ p = getnode (); p->type = DIRS; p->key = xstrdup (dp->d_name); if (addnode (list, p) != 0) freenode (p); do_it_again: errno = 0; } if (errno != 0) { int save_errno = errno; (void) closedir (dirp); errno = save_errno; return 1; } (void) closedir (dirp); if (tmp != NULL) xfree (tmp); return (0); }
static char *config_path(char *cmd) { FILE *fp; char *fname; static char varfmt[] = "TET_%.32s_PATH"; char var[sizeof varfmt + 32]; int varlen; char buf[BUFSIZ]; char *p, *val; /* return now if cmd has a path prefix */ for (p = cmd; *p; p++) if (ISDIRSEP(*p)) return(cmd); /* ** get the name of the configuration file out of the environment ** received from tcc */ if ((fname = getenv("TET_CONFIG")) == (char *) 0 || !*fname) return(cmd); /* generate the name of the config variable that we are looking for */ (void) sprintf(var, varfmt, cmd); varlen = strlen(var); for (p = var; *p; p++) if (islower(*p)) *p = toupper(*p); /* open the config file */ if ((fp = fopen(fname, "r")) == (FILE *) 0) { (void) fprintf(stderr, "warning: can't open %s: errno = %d\n", fname, errno); return(cmd); } /* ** search for the variable in the config file, ignoring ** blank lines, comments and badly formatted lines; ** if we find the variable that we are looking for, arrange to ** return its value */ while (fgets(buf, sizeof buf, fp) != (char *) 0) { for (p = buf; p < &buf[sizeof buf]; p++) if (*p == '\n') { *p = '\0'; break; } if ( buf[0] == '\0' || buf[0] == '#' || (p = strchr(buf, '=')) == (char *) 0 || varlen != (int) (p - buf) || strncmp(buf, var, (size_t) varlen) ) { continue; } if ( *(val = p + 1) != '\0' && (p = (char *) malloc(strlen(val) + 1)) != (char *) 0 ) { (void) strcpy(p, val); cmd = p; } break; } /* finally, close the config file and return */ (void) fclose(fp); return(cmd); }
/* * jt_tool() * * Execute an external program, optionally setting various environment * variables. * * cmd Name of command to execute. * ops Bitmask of operations to perform before the execution. * argc Argument count. * argv Command line arguments. The class name will be argv[1]. * suffix Suffix to append to the class name. * * This routine does not return. If an error occurs, it exits with a failure * status. */ void jt_tool(char *cmd, int ops, int argc, char **argv, char *suffix) { /* The first two are static, since they are passed to jt_putenv() */ static char newclasspath[MAXPATH]; static char newlibpaths[NELEM(libpathvars)][MAXPATH]; char *tetroot; char *classpath; char *libpath; int i; char **newargs; char *cp; /* Verify we have at least one argument */ if (argc < 2) jt_err(argv[0], "incorrect argument count"); /* Verify TET_ROOT is set in the environment */ tetroot = getenv("TET_ROOT"); if (tetroot == NULL || tetroot[0] == '\0') jt_err(argv[0], "TET_ROOT is NULL or not set in environment"); /* If required, set the CLASSPATH environment variable to include the * JET jar file. */ if (ops & OP_SETCLASSPATH) { classpath = getenv("CLASSPATH"); if (classpath == NULL || classpath[0] == '\0') { sprintf(newclasspath, "CLASSPATH=.%c%s%clib%cjava%cjet.jar", PATHSEP, tetroot, DIRSEP, DIRSEP, DIRSEP); } else { sprintf(newclasspath, "CLASSPATH=%s%clib%cjava%cjet.jar%c%s%c.", tetroot, DIRSEP, DIRSEP, DIRSEP, PATHSEP, classpath, PATHSEP); } if (jt_putenv(newclasspath) != 0) jt_err(argv[0], "error setting CLASSPATH in environment"); } /* If required, set the environment variable used as the search path * for shared libraries to include the directory containing libjet. */ if (ops & OP_SETLIBPATH) { for (i = 0; i < NELEM(libpathvars); i++) { libpath = getenv(libpathvars[i]); if (libpath == NULL) { sprintf(newlibpaths[i], "%s=%s%clib%cjava", libpathvars[i], tetroot, DIRSEP, DIRSEP); } else { sprintf(newlibpaths[i], "%s=%s%clib%cjava%c%s", libpathvars[i], tetroot, DIRSEP, DIRSEP, PATHSEP, libpath); } if (jt_putenv(newlibpaths[i]) != 0) jt_err(argv[0], "error setting %s in environment", libpathvars[i]); } } /* Prepare command and new argument vector */ newargs = malloc(sizeof(*newargs) * (argc + 1)); if (newargs == NULL) jt_err(argv[0], "memory allocation failure"); newargs[0] = cmd; newargs[1] = malloc(strlen(argv[1]) + strlen(suffix) + 1); if (newargs[1] == NULL) jt_err(argv[0], "memory allocation failure"); /* Copy the classname and suffix into the first argument */ sprintf(newargs[1], "%s%s", argv[1], suffix); /* Some versions of Sun's javac on Win32 don't recognize '/' as a * directory separator when it comes to verifying that the class is in * a correctly named file. So we swap to backslashes here. */ if (ops & OP_SWAPDIRSEP) { for (cp = newargs[1]; *cp != '\0'; cp++) if (ISDIRSEP(*cp)) *cp = DIRSEP; } for (i = 2; i <= argc; i++) newargs[i] = argv[i]; /* Exec command */ cmd = config_path(cmd); jt_execvp(cmd, newargs); jt_err(argv[0], "error executing command \"%s\": %s", cmd, strerror(errno)); }
static char * canonicalize (const char *name, char *resolved) { char *rpath, *dest, *extra_buf = NULL; const char *start, *end, *rpath_limit; long int path_max; int num_links = 0, old_errno; if (name == NULL) { /* As per Single Unix Specification V2 we must return an error if either parameter is a null pointer. We extend this to allow the RESOLVED parameter to be NULL in case the we are expected to allocate the room for the return value. */ __set_errno (EINVAL); return NULL; } if (name[0] == '\0') { /* As per Single Unix Specification V2 we must return an error if the name argument points to an empty string. */ __set_errno (ENOENT); return NULL; } #ifdef __WIN32__ { char *lpFilePart; int len; // fprintf(stderr, "name: %s\n", name); rpath = resolved ? __builtin_alloca (MAX_PATH) : malloc (MAX_PATH); // unix2winpath (name); // fprintf(stderr, "name: %s\n", name); len = GetFullPathName(name, MAX_PATH, rpath, &lpFilePart); /* GetFullPathName returns bogus paths for *nix-style paths, like * /foo/bar - it just prepends current drive to them. Keep them * intact (they need to be for relocation to work!). */ if (name[0] == '/') { strncpy (rpath, name, MAX_PATH - 1); rpath[MAX_PATH - 1] = '\0'; len = strlen (rpath); } // fprintf(stderr, "rpath: %s\n", rpath); if (len == 0) { //set_werrno; return NULL; } if (len > MAX_PATH) { if (resolved) __set_errno(ENAMETOOLONG); else { rpath = realloc(rpath, len + 2); GetFullPathName(name, len, rpath, &lpFilePart); // fprintf(stderr, "rpath: %s\n", rpath); } } // if ( ISDIRSEP(name[strlen(name)]) && !ISDIRSEP(rpath[len]) ) { // rpath[len] = '\\'; // rpath[len + 1] = 0; // } old_errno = errno; //if (!access (rpath, D_OK) && !ISDIRSEP(rpath[len - 1]) ){ if (!access (rpath, R_OK) && !ISDIRSEP(rpath[len - 1]) ){ rpath[len] = '\\'; rpath[len + 1] = 0; } errno = old_errno; win2unixpath (rpath); // fprintf(stderr, "rpath: %s\n", rpath); return resolved ? strcpy(resolved, rpath) : rpath ; } #else /* __WIN32__ */ #ifdef PATH_MAX path_max = PATH_MAX; #else path_max = pathconf (name, _PC_PATH_MAX); if (path_max <= 0) path_max = 1024; #endif rpath = resolved ? __builtin_alloca (path_max) : malloc (path_max); rpath_limit = rpath + path_max; if (name[0] != '/') { if (!__getcwd (rpath, path_max)) { rpath[0] = '\0'; goto error; } dest = strchr (rpath, '\0'); } else { rpath[0] = '/'; dest = rpath + 1; } for (start = end = name; *start; start = end) { #ifdef _LIBC struct stat64 st; #else struct stat st; #endif int n; /* Skip sequence of multiple path-separators. */ while (*start == '/') ++start; /* Find end of path component. */ for (end = start; *end && *end != '/'; ++end) /* Nothing. */; if (end - start == 0) break; else if (end - start == 1 && start[0] == '.') /* nothing */; else if (end - start == 2 && start[0] == '.' && start[1] == '.') { /* Back up to previous component, ignore if at root already. */ if (dest > rpath + 1) while ((--dest)[-1] != '/'); } else { size_t new_size; if (dest[-1] != '/') *dest++ = '/'; if (dest + (end - start) >= rpath_limit) { ptrdiff_t dest_offset = dest - rpath; if (resolved) { __set_errno (ENAMETOOLONG); if (dest > rpath + 1) dest--; *dest = '\0'; goto error; } new_size = rpath_limit - rpath; if (end - start + 1 > path_max) new_size += end - start + 1; else new_size += path_max; rpath = realloc (rpath, new_size); rpath_limit = rpath + new_size; if (rpath == NULL) return NULL; dest = rpath + dest_offset; } #ifdef _LIBC dest = __mempcpy (dest, start, end - start); #else memcpy (dest, start, end - start); dest += end - start; #endif *dest = '\0'; #ifdef _LIBC if (__lxstat64 (_STAT_VER, rpath, &st) < 0) #else if (lstat (rpath, &st) < 0) #endif goto error; #if HAVE_READLINK if (S_ISLNK (st.st_mode)) { char *buf = __builtin_alloca (path_max); size_t len; if (++num_links > MAXSYMLINKS) { __set_errno (ELOOP); goto error; } n = __readlink (rpath, buf, path_max); if (n < 0) goto error; buf[n] = '\0'; if (!extra_buf) extra_buf = __builtin_alloca (path_max); len = strlen (end); if ((long int) (n + len) >= path_max) { __set_errno (ENAMETOOLONG); goto error; } /* Careful here, end may be a pointer into extra_buf... */ memmove (&extra_buf[n], end, len + 1); name = end = memcpy (extra_buf, buf, n); if (buf[0] == '/') dest = rpath + 1; /* It's an absolute symlink */ else /* Back up to previous component, ignore if at root already: */ if (dest > rpath + 1) while ((--dest)[-1] != '/'); } #endif } } if (dest > rpath + 1 && dest[-1] == '/') --dest; *dest = '\0'; return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; error: if (resolved) strcpy (resolved, rpath); else free (rpath); return NULL; #endif /* __WIN32__ */ }