Annotation of src/usr.bin/cvs/import.c, Revision 1.1
1.1 ! krapht 1: /* $OpenBSD$ */
! 2: /*
! 3: * Copyright (c) 2004 Joris Vink <amni@pandora.be>
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. The name of the author may not be used to endorse or promote products
! 13: * derived from this software without specific prior written permission.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: #include <sys/types.h>
! 28: #include <sys/queue.h>
! 29:
! 30: #include <err.h>
! 31: #include <dirent.h>
! 32: #include <errno.h>
! 33: #include <stdio.h>
! 34: #include <stdlib.h>
! 35: #include <unistd.h>
! 36: #include <string.h>
! 37: #include <sysexits.h>
! 38:
! 39: #include "cvs.h"
! 40: #include "log.h"
! 41: #include "file.h"
! 42: #include "proto.h"
! 43:
! 44: static int do_import(struct cvsroot *, char **);
! 45: static int cvs_import_dir(struct cvsroot *, char *, char *);
! 46: static int cvs_import_file(struct cvsroot *, CVSFILE *);
! 47:
! 48: /*
! 49: * cvs_import()
! 50: *
! 51: * Handler for the `cvs import' command.
! 52: */
! 53: int
! 54: cvs_import(int argc, char **argv)
! 55: {
! 56: int ch, flags;
! 57: char *repo, *vendor, *release;
! 58: struct cvsroot *root;
! 59:
! 60: flags = CF_IGNORE|CF_NOSYMS;
! 61:
! 62: while ((ch = getopt(argc, argv, "b:dI:k:m:")) != -1) {
! 63: switch (ch) {
! 64: case 'b':
! 65: case 'd':
! 66: break;
! 67: case 'I':
! 68: if (cvs_file_ignore(optarg) < 0) {
! 69: cvs_log(LP_ERR, "failed to add `%s' to list "
! 70: "of ignore patterns", optarg);
! 71: return (EX_USAGE);
! 72: }
! 73: break;
! 74: case 'k':
! 75: break;
! 76: case 'm':
! 77: cvs_msg = optarg;
! 78: break;
! 79: default:
! 80: return (EX_USAGE);
! 81: }
! 82: }
! 83:
! 84: argc -= optind;
! 85: argv += optind;
! 86: if (argc > 4)
! 87: return (EX_USAGE);
! 88:
! 89: cvs_files = cvs_file_get(".", flags);
! 90: if (cvs_files == NULL)
! 91: return (EX_DATAERR);
! 92:
! 93: root = CVS_DIR_ROOT(cvs_files);
! 94: if (root->cr_method != CVS_METHOD_LOCAL) {
! 95: cvs_connect(root);
! 96:
! 97: /* Do it */
! 98: do_import(root, argv);
! 99:
! 100: cvs_disconnect(root);
! 101: }
! 102:
! 103: return (0);
! 104: }
! 105:
! 106: /*
! 107: * Import a module using a server
! 108: */
! 109: static int
! 110: do_import(struct cvsroot *root, char **argv)
! 111: {
! 112: char repository[MAXPATHLEN];
! 113:
! 114: /* XXX temporary */
! 115: if (cvs_sendarg(root, "-m testlog", 0) < 0) {
! 116: cvs_log(LP_ERR, "failed to send temporary logmessage");
! 117: return (-1);
! 118: }
! 119:
! 120: /* send arguments */
! 121: if (cvs_sendarg(root, argv[0], 0) < 0 ||
! 122: cvs_sendarg(root, argv[1], 0) < 0 ||
! 123: cvs_sendarg(root, argv[2], 0) < 0) {
! 124: cvs_log(LP_ERR, "failed to send arguments");
! 125: return (-1);
! 126: }
! 127:
! 128: /* create the repository name */
! 129: snprintf(repository, sizeof(repository), "%s/%s",
! 130: root->cr_dir, argv[0]);
! 131:
! 132: cvs_files = cvs_file_get(".", 0);
! 133: if (cvs_files == NULL) {
! 134: cvs_log(LP_ERR, "failed to obtain info on root");
! 135: return (-1);
! 136: }
! 137:
! 138: /* walk the root directory */
! 139: cvs_import_dir(root, ".", repository);
! 140:
! 141: /* send import request */
! 142: if (cvs_senddir(root, cvs_files) < 0 ||
! 143: cvs_sendraw(root, repository, strlen(repository) < 0 ||
! 144: cvs_sendraw(root, "\n", 1) < 0 ||
! 145: cvs_sendreq(root, CVS_REQ_IMPORT, NULL) < 0))
! 146: cvs_log(LP_ERR, "failed to import repository %s",
! 147: repository);
! 148:
! 149:
! 150: /* done */
! 151: return (0);
! 152: }
! 153:
! 154: static int
! 155: cvs_import_dir(struct cvsroot *root, char *dirname, char *repo)
! 156: {
! 157: char *cwd;
! 158: char *basedir;
! 159: char cvsdir[MAXPATHLEN];
! 160: CVSFILE *parent, *fp;
! 161:
! 162: if ((basedir = strrchr(dirname, '/')) != NULL)
! 163: basedir++;
! 164: else
! 165: basedir = dirname;
! 166:
! 167: /* save current directory */
! 168: if ((cwd = getcwd(NULL, MAXPATHLEN)) == NULL) {
! 169: cvs_log(LP_ERR, "couldn't save current directory");
! 170: return (-1);
! 171: }
! 172:
! 173: /* Switch to the new directory */
! 174: if (chdir(basedir) < 0) {
! 175: cvs_log(LP_ERR, "failed to switch to directory %s", dirname);
! 176: return (-1);
! 177: }
! 178:
! 179: if (!strcmp(dirname, "."))
! 180: strlcpy(cvsdir, repo, sizeof(cvsdir));
! 181: else
! 182: snprintf(cvsdir, sizeof(cvsdir), "%s/%s", repo, dirname);
! 183:
! 184: /* Obtain information about the directory */
! 185: parent = cvs_file_get(".", CF_SORT|CF_RECURSE|CF_IGNORE);
! 186: if (parent == NULL) {
! 187: cvs_log(LP_ERR, "couldn't obtain info on %s", dirname);
! 188: return (-1);
! 189: }
! 190:
! 191: if (cvs_sendreq(root, CVS_REQ_DIRECTORY, dirname) < 0 ||
! 192: cvs_sendraw(root, cvsdir, strlen(cvsdir)) < 0 ||
! 193: cvs_sendraw(root, "\n", 1) < 0)
! 194: return (-1);
! 195:
! 196: printf("Importing %s\n", dirname);
! 197:
! 198: /* Walk the directory */
! 199: TAILQ_FOREACH(fp, &(parent->cf_ddat->cd_files), cf_list) {
! 200: /* If we have a sub directory, skip it for now */
! 201: if (fp->cf_type == DT_DIR)
! 202: continue;
! 203:
! 204: /* Import the file */
! 205: if (cvs_import_file(root, fp) < 0)
! 206: #if 0
! 207: cvs_log(LP_ERR, "failed to import %s", fp->cf_path);
! 208: #else
! 209: cvs_log(LP_ERR, "failed to import %s", NULL);
! 210: #endif
! 211: }
! 212:
! 213: /* Walk the subdirectories */
! 214: TAILQ_FOREACH(fp, &(parent->cf_ddat->cd_files), cf_list) {
! 215: if (fp->cf_type != DT_DIR)
! 216: continue;
! 217: if (!strcmp(CVS_FILE_NAME(fp), ".") ||
! 218: !strcmp(CVS_FILE_NAME(fp), ".."))
! 219: continue;
! 220:
! 221: if (strcmp(dirname, "."))
! 222: snprintf(cvsdir, sizeof(cvsdir), "%s/%s",
! 223: dirname, CVS_FILE_NAME(fp));
! 224: else
! 225: strlcpy(cvsdir, CVS_FILE_NAME(fp), sizeof(cvsdir));
! 226: if (cvs_import_dir(root, cvsdir, repo) < 0)
! 227: cvs_log(LP_ERR, "failed to import directory %s",
! 228: CVS_FILE_NAME(fp));
! 229: }
! 230:
! 231: cvs_file_free(parent);
! 232:
! 233: /* restore working directory */
! 234: if (chdir(cwd) < 0) {
! 235: cvs_log(LP_ERR, "failed to restore directory %s", cwd);
! 236: return (-1);
! 237: }
! 238:
! 239: return (0);
! 240: }
! 241:
! 242: /*
! 243: * Import a file
! 244: */
! 245: static int
! 246: cvs_import_file(struct cvsroot *root, CVSFILE *fp)
! 247: {
! 248: /* Send a Modified response follwed by the
! 249: * file's mode, length and contents
! 250: */
! 251: if (cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(fp)) < 0)
! 252: return (-1);
! 253: if (cvs_sendfile(root, CVS_FILE_NAME(fp)) < 0)
! 254: return (-1);
! 255:
! 256: return (0);
! 257: }