Example #1
0
File: repos.cpp Project: acml/cvsnt
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;
	}
}
Example #2
0
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);
}
Example #3
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])));
}
Example #4
0
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
Example #5
0
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;
}
Example #6
0
/* 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;
}
Example #7
0
/*
 * 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);
}
Example #8
0
/* 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;
}
Example #10
0
/*
 * 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);
}
Example #11
0
File: repos.cpp Project: acml/cvsnt
/*
 * 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);
}
Example #12
0
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;
	}
}
Example #13
0
/*
 * 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);
}
Example #14
0
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);
}
Example #15
0
/*
 * 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);
}
Example #16
0
/*
 * 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);
}
Example #17
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);
}
Example #18
0
/*
 * 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));
}
Example #19
0
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__ */
}