Ejemplo n.º 1
0
/*ARGSUSED*/
static int register_subdir_proc (Node *p, void *closure)
{
    List *entries = (List *) closure;

    Subdir_Register (entries, (char *) NULL, p->key);
    return 0;
}
Ejemplo n.º 2
0
int cvsrename(int argc, char **argv)
{
    int c;
    int err = 0;
	char *repos_file1, *repos_file2;
	char *root1, *root2;
	const char *filename1, *filename2, *dir1, *dir2;
	int rootlen;
	List *ent,*ent2;
	Node *node;
	Entnode *entnode;
	const char *cwd;

	if (argc == -1)
		usage (rename_usage);

	quiet = 0;

    optind = 0;
    while ((c = getopt (argc, argv, "+q")) != -1)
    {
	switch (c)
	{
	case 'q':
		quiet = 1;
		break;
    case '?':
    default:
		usage (rename_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

	if(argc!=2)
	{
		usage(rename_usage);
	};

	error(0,0,"Warning: rename is still experimental and may not behave as you would expect");

	if(current_parsed_root->isremote)
	{
		if(!supported_request("Rename"))
			error(1,0,"Remote server does not support rename");
		if(!supported_request("Can-Rename"))
			error(1,0,"Renames are currently disabled");
	}

	if(!strcmp(argv[0],argv[1]))
		return 0;

	rootlen = strlen(current_parsed_root->directory);

	if(!isfile(argv[0]))
		error(1,0,"%s does not exist",argv[0]);

	if(isfile(argv[1]) && fncmp(argv[0],argv[1])) /* We allow case renames (on Unix this is redundant) */
		error(1,0,"%s already exists",argv[1]);

	if(isdir(argv[0]))
		error(1,0,"Directory renames are not currently supported");

	validate_file(argv[0],&root1, &repos_file1, &filename1, &dir1, 1);
	validate_file(argv[1],&root2, &repos_file2, &filename2, &dir2, 0);

	if(strcmp(root1,root2) || strcmp(root1,current_parsed_root->original))
		error(1,0,"%s and %s are in different repositories",argv[0],argv[1]);

	xfree(root1);
	xfree(root2);

	repos_file1 = (char*)xrealloc(repos_file1, strlen(filename1)+strlen(repos_file1)+rootlen+10);
	repos_file2 = (char*)xrealloc(repos_file2, strlen(filename2)+strlen(repos_file2)+rootlen+10);
	memmove(repos_file1+rootlen+1,repos_file1,strlen(repos_file1)+1);
	memmove(repos_file2+rootlen+1,repos_file2,strlen(repos_file2)+1);
	strcpy(repos_file1,current_parsed_root->directory);
	strcpy(repos_file2,current_parsed_root->directory);
	repos_file1[rootlen]='/';
	repos_file2[rootlen]='/';
	strcat(repos_file1,"/");
	strcat(repos_file2,"/");
	strcat(repos_file1,filename1);
	strcat(repos_file2,filename2);

	if(fncmp(argv[0],argv[1]))
		set_mapping(dir2,repos_file2+rootlen+1,""); /* Delete old file */
	if(fncmp(dir1,dir2))
		set_mapping(dir1,repos_file1+rootlen+1,""); 
	set_mapping(dir2,repos_file1+rootlen+1,repos_file2+rootlen+1); /* Rename to new file */

	cwd = xgetwd();
	if(CVS_CHDIR(dir1))
		error(1,errno,"Couldn't chdir to %s",dir1);
	ent = Entries_Open(0, NULL);
	node = findnode_fn(ent, filename1);
	entnode=(Entnode*)node->data;

	if(!node)
	{
		error(1,0,"%s is not listed in CVS/Entries",filename1);
		CVS_CHDIR(cwd);
		xfree(cwd);
		return 1;
	}

	if(!fncmp(dir1,dir2))
		Rename_Entry(ent,filename1,filename2);
	else
	{
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir2))
			error(1,errno,"Couldn't chdir to %s",dir2);
		ent2 = Entries_Open(0, NULL);
		if(entnode->type==ENT_FILE)
			Register(ent2,(char*)filename2,entnode->version,entnode->timestamp,entnode->options,entnode->tag,entnode->date,entnode->conflict,entnode->merge_from_tag_1,entnode->merge_from_tag_2,entnode->rcs_timestamp,entnode->edit_revision,entnode->edit_tag,entnode->edit_bugid,entnode->md5);
		else if(entnode->type==ENT_SUBDIR)
			Subdir_Register(ent2,NULL,filename2);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);

		Entries_Close(ent2);
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir1))
			error(1,errno,"Couldn't chdir to %s",dir1);

		if(entnode->type==ENT_SUBDIR)
			Subdir_Deregister(ent,NULL,filename1);
		else if(entnode->type==ENT_FILE)
			Scratch_Entry(ent,filename1);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);
	}
	Entries_Close(ent);

	CVS_RENAME(argv[0],argv[1]);

	if(isdir(argv[1]))
	{
		char *tmp=(char*)xmalloc(strlen(argv[1])+strlen(CVSADM_VIRTREPOS)+10);
		FILE *fp;
		sprintf(tmp,"%s/%s",argv[1],CVSADM_VIRTREPOS);
		fp = fopen(tmp,"w");
		if(!fp)
			error(0,errno,"Couldn't write %s",tmp);
		fprintf(fp,"%s\n",repos_file2+rootlen+1);
		fclose(fp);
	}

	xfree(repos_file1);
	xfree(repos_file2);
	xfree(dir1);
	xfree(dir2);
	CVS_CHDIR(cwd);
	xfree(cwd);

    return (err);
}
Ejemplo n.º 3
0
/*
 * Add this directory to the list of data to be printed for a directory and
 * decide whether to tell the recursion processor whether to continue
 * recursing or not.
 */
static Dtype
ls_direntproc (void *callerdat, const char *dir, const char *repos,
               const char *update_dir, List *entries)
{
    Dtype retval;
    Node *p;

    /* Due to the way we called start_recursion() from ls_proc() with a single
     * argument at a time, we can assume that if we don't yet have a parent
     * directory in DIRS then this directory should be processed.
     */

    if (strcmp (dir, "."))
    {
        /* Search for our parent directory.  */
	char *parent;
        parent = xmalloc (strlen (update_dir) - strlen (dir) + 1);
        strncpy (parent, update_dir, strlen (update_dir) - strlen (dir));
        parent[strlen (update_dir) - strlen (dir)] = '\0';
        strip_trailing_slashes (parent);
        p = findnode (callerdat, parent);
    }
    else
        p = NULL;

    if (p)
    {
	/* Push this dir onto our parent directory's listing.  */
	Node *n = getnode();

	if (entries_format)
	    n->data = Xasprintf ("D/%s////\n", dir);
	else if (long_format)
	{
	    struct long_format_data *out =
		    xmalloc (sizeof (struct long_format_data));
	    out->header = xstrdup ("d--- ");
	    out->time = gmformat_time_t (unix_time_stamp (repos));
	    out->footer = Xasprintf ("%12s%s%s", "",
                                     show_dead_revs ? "     " : "", dir);
	    n->data = out;
	    n->delproc = long_format_data_delproc;
	}
	else
	    n->data = Xasprintf ("%s\n", dir);

	addnode (p->data, n);
    }

    if (!p || recurse)
    {
	/* Create a new list for this directory.  */
	p = getnode ();
	p->key = xstrdup (strcmp (update_dir, ".") ? update_dir : "");
	p->data = getlist ();
        p->delproc = ls_delproc;
	addnode (callerdat, p);

	/* Create a local directory and mark it as needing deletion.  This is
         * the behavior the recursion processor relies upon, a la update &
         * checkout.
         */
	if (!isdir (dir))
        {
	    int nonbranch;
	    if (show_tag == NULL && show_date == NULL)
	    {
		ParseTag (&show_tag, &show_date, &nonbranch);
		set_tag = true;
	    }

	    if (!created_dir)
		created_dir = xstrdup (update_dir);

	    make_directory (dir);
	    Create_Admin (dir, update_dir, repos, show_tag, show_date,
			  nonbranch, 0, 0);
	    Subdir_Register (entries, NULL, dir);
	}

	/* Tell do_recursion to keep going.  */
	retval = R_PROCESS;
    }
    else
        retval = R_SKIP_ALL;

    return retval;
}