[BACK]Return to import.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

File: [local] / src / usr.bin / cvs / import.c (download)

Revision 1.1, Tue Nov 9 20:46:02 2004 UTC (19 years, 6 months ago) by krapht
Branch: MAIN

import code from Joris Vink <amni at pandora dot be>

/*	$OpenBSD: import.c,v 1.1 2004/11/09 20:46:02 krapht Exp $	*/
/*
 * Copyright (c) 2004 Joris Vink <amni@pandora.be>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/queue.h>

#include <err.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sysexits.h>

#include "cvs.h"
#include "log.h"
#include "file.h"
#include "proto.h"

static int do_import(struct cvsroot *, char **);
static int cvs_import_dir(struct cvsroot *, char *, char *);
static int cvs_import_file(struct cvsroot *, CVSFILE *);

/*
 * cvs_import()
 *
 * Handler for the `cvs import' command.
 */
int
cvs_import(int argc, char **argv)
{
	int ch, flags;
	char *repo, *vendor, *release;
	struct cvsroot *root;

	flags = CF_IGNORE|CF_NOSYMS;

	while ((ch = getopt(argc, argv, "b:dI:k:m:")) != -1) {
		switch (ch) {
		case 'b':
		case 'd':
			break;
		case 'I':
			if (cvs_file_ignore(optarg) < 0) {
				cvs_log(LP_ERR, "failed to add `%s' to list "
				    "of ignore patterns", optarg);
				return (EX_USAGE);
			}
			break;
		case 'k':
			break;
		case 'm':
			cvs_msg = optarg;
			break;
		default:
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;
	if (argc > 4)
		return (EX_USAGE);

	cvs_files = cvs_file_get(".", flags);
	if (cvs_files == NULL)
		return (EX_DATAERR);

	root = CVS_DIR_ROOT(cvs_files);
	if (root->cr_method != CVS_METHOD_LOCAL) {
		cvs_connect(root);

		/* Do it */
		do_import(root, argv);

		cvs_disconnect(root);
	}

	return (0);
}

/*
 * Import a module using a server
 */
static int
do_import(struct cvsroot *root, char **argv)
{
	char repository[MAXPATHLEN];

	/* XXX temporary */
	if (cvs_sendarg(root, "-m testlog", 0) < 0) {
		cvs_log(LP_ERR, "failed to send temporary logmessage");
		return (-1);
	}

	/* send arguments */
	if (cvs_sendarg(root, argv[0], 0) < 0 ||
	    cvs_sendarg(root, argv[1], 0) < 0 ||
	    cvs_sendarg(root, argv[2], 0) < 0) {
		cvs_log(LP_ERR, "failed to send arguments");
 		return (-1);
	}

	/* create the repository name */
	snprintf(repository, sizeof(repository), "%s/%s",
	    root->cr_dir, argv[0]);

	cvs_files = cvs_file_get(".", 0);
	if (cvs_files == NULL) {
		cvs_log(LP_ERR, "failed to obtain info on root");
		return (-1);
	}

	/* walk the root directory */
	cvs_import_dir(root, ".", repository);

	/* send import request */
	if (cvs_senddir(root, cvs_files) < 0 ||
	    cvs_sendraw(root, repository, strlen(repository) < 0 ||
	    cvs_sendraw(root, "\n", 1) < 0 ||
	    cvs_sendreq(root, CVS_REQ_IMPORT, NULL) < 0))
		cvs_log(LP_ERR, "failed to import repository %s",
		    repository);


	/* done */
	return (0);
}

static int
cvs_import_dir(struct cvsroot *root, char *dirname, char *repo)
{
	char *cwd;
	char *basedir;
	char cvsdir[MAXPATHLEN];
	CVSFILE *parent, *fp;

	if ((basedir = strrchr(dirname, '/')) != NULL)
		basedir++;
	else
		basedir = dirname;

	/* save current directory */
	if ((cwd = getcwd(NULL, MAXPATHLEN)) == NULL) {
		cvs_log(LP_ERR, "couldn't save current directory");
		return (-1);
	}

	/* Switch to the new directory */
	if (chdir(basedir) < 0) {
		cvs_log(LP_ERR, "failed to switch to directory %s", dirname);
		return (-1);
	}

	if (!strcmp(dirname, "."))
		strlcpy(cvsdir, repo, sizeof(cvsdir));
	else
		snprintf(cvsdir, sizeof(cvsdir), "%s/%s", repo, dirname);

	/* Obtain information about the directory */
	parent = cvs_file_get(".", CF_SORT|CF_RECURSE|CF_IGNORE);
	if (parent == NULL) {
		cvs_log(LP_ERR, "couldn't obtain info on %s", dirname);
		return (-1);
	}

	if (cvs_sendreq(root, CVS_REQ_DIRECTORY, dirname) < 0 ||
	    cvs_sendraw(root, cvsdir, strlen(cvsdir)) < 0 ||
	    cvs_sendraw(root, "\n", 1) < 0)
		return (-1);

	printf("Importing %s\n", dirname);

	/* Walk the directory */
	TAILQ_FOREACH(fp, &(parent->cf_ddat->cd_files), cf_list) {
		/* If we have a sub directory, skip it for now */
		if (fp->cf_type == DT_DIR)
			continue;

		/* Import the file */
		if (cvs_import_file(root, fp) < 0)
#if 0
			cvs_log(LP_ERR, "failed to import %s", fp->cf_path);
#else
			cvs_log(LP_ERR, "failed to import %s", NULL);
#endif
	}

	/* Walk the subdirectories */
	TAILQ_FOREACH(fp, &(parent->cf_ddat->cd_files), cf_list) {
		if (fp->cf_type != DT_DIR)
			continue;
		if (!strcmp(CVS_FILE_NAME(fp), ".") ||
		    !strcmp(CVS_FILE_NAME(fp), ".."))
			continue;

		if (strcmp(dirname, "."))
			snprintf(cvsdir, sizeof(cvsdir), "%s/%s",
			    dirname, CVS_FILE_NAME(fp));
		else
			strlcpy(cvsdir, CVS_FILE_NAME(fp), sizeof(cvsdir));
		if (cvs_import_dir(root, cvsdir, repo) < 0)
			cvs_log(LP_ERR, "failed to import directory %s",
			    CVS_FILE_NAME(fp));
	}

	cvs_file_free(parent);

	/* restore working directory */
	if (chdir(cwd) < 0) {
		cvs_log(LP_ERR, "failed to restore directory %s", cwd);
		return (-1);
	}

	return (0);
}

/*
 * Import a file
 */
static int
cvs_import_file(struct cvsroot *root, CVSFILE *fp)
{
	/* Send a Modified response follwed by the
	 * file's mode, length and contents
	 */
	if (cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(fp)) < 0)
		return (-1);
	if (cvs_sendfile(root, CVS_FILE_NAME(fp)) < 0)
		return (-1);

	return (0);
}