Annotation of src/usr.bin/cvs/add.c, Revision 1.47
1.47 ! joris 1: /* $OpenBSD: add.c,v 1.46 2006/05/29 06:25:06 joris Exp $ */
1.1 jfb 2: /*
1.43 joris 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.1 jfb 4: *
1.43 joris 5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 jfb 8: *
1.43 joris 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 jfb 16: */
17:
1.37 xsa 18: #include "includes.h"
1.1 jfb 19:
20: #include "cvs.h"
1.43 joris 21: #include "diff.h"
1.1 jfb 22: #include "log.h"
1.2 jfb 23: #include "proto.h"
1.1 jfb 24:
1.43 joris 25: int cvs_add(int, char **);
26: void cvs_add_local(struct cvs_file *);
1.1 jfb 27:
1.45 joris 28: static void add_directory(struct cvs_file *);
29: static void add_file(struct cvs_file *);
30:
1.43 joris 31: char *logmsg;
1.21 jfb 32:
33: struct cvs_cmd cvs_cmd_add = {
34: CVS_OP_ADD, CVS_REQ_ADD, "add",
35: { "ad", "new" },
1.43 joris 36: "Add a new file or directory to the repository",
37: "[-m message] ...",
1.47 ! joris 38: "m:",
1.21 jfb 39: NULL,
1.43 joris 40: cvs_add
1.15 joris 41: };
1.3 jfb 42:
1.43 joris 43: int
44: cvs_add(int argc, char **argv)
1.1 jfb 45: {
1.15 joris 46: int ch;
1.43 joris 47: int flags;
48: struct cvs_recursion cr;
1.1 jfb 49:
1.45 joris 50: flags = CR_REPO;
1.1 jfb 51:
1.43 joris 52: while ((ch = getopt(argc, argv, cvs_cmd_add.cmd_opts)) != -1) {
1.1 jfb 53: switch (ch) {
54: case 'm':
1.43 joris 55: logmsg = xstrdup(optarg);
1.1 jfb 56: break;
57: default:
1.43 joris 58: fatal("%s", cvs_cmd_add.cmd_synopsis);
1.1 jfb 59: }
60: }
61:
1.43 joris 62: argc -= optind;
63: argv += optind;
1.28 xsa 64:
1.46 joris 65: if (argc == 0)
66: fatal("%s", cvs_cmd_add.cmd_synopsis);
67:
1.43 joris 68: cr.enterdir = NULL;
69: cr.leavedir = NULL;
70: cr.local = cvs_add_local;
71: cr.remote = NULL;
72: cr.flags = flags;
73:
1.46 joris 74: cvs_file_run(argc, argv, &cr);
1.3 jfb 75: return (0);
76: }
77:
1.43 joris 78: void
79: cvs_add_local(struct cvs_file *cf)
1.3 jfb 80: {
1.45 joris 81: cvs_log(LP_TRACE, "cvs_add_local(%s)", cf->file_path);
82:
83: cvs_file_classify(cf, 0);
84:
85: if (cf->file_type == CVS_DIR)
86: add_directory(cf);
87: else
88: add_file(cf);
89: }
90:
91: static void
92: add_directory(struct cvs_file *cf)
93: {
94: int l;
95: struct stat st;
1.44 joris 96: CVSENTRIES *entlist;
1.45 joris 97: char *entry, *repo;
98:
99: cvs_log(LP_TRACE, "add_directory(%s)", cf->file_path);
1.44 joris 100:
1.45 joris 101: entry = xmalloc(MAXPATHLEN);
102: l = snprintf(entry, MAXPATHLEN, "%s%s", cf->file_rpath, RCS_FILE_EXT);
103: if (l == -1 || l >= MAXPATHLEN)
104: fatal("cvs_add_local: overflow");
105:
106: if (stat(entry, &st) != -1) {
107: cvs_log(LP_NOTICE, "cannot add directory %s: "
108: "a file with that name already exists",
109: cf->file_path);
110: } else {
111: l = snprintf(entry, MAXPATHLEN, "%s/%s", cf->file_path,
112: CVS_PATH_CVSDIR);
113: if (l == -1 || l >= MAXPATHLEN)
114: fatal("add_directory: overflow");
115:
116: if (stat(entry, &st) != -1) {
117: if (!S_ISDIR(st.st_mode)) {
118: cvs_log(LP_ERR, "%s exists but is not "
119: "directory", entry);
120: } else {
121: cvs_log(LP_NOTICE, "%s already exists",
122: entry);
123: }
124: } else {
125: if (mkdir(cf->file_rpath, 0755) == -1 &&
126: errno != EEXIST)
127: fatal("add_directory: %s: %s", cf->file_path,
128: strerror(errno));
129:
130: repo = xmalloc(MAXPATHLEN);
131: cvs_get_repository_name(cf->file_wd, repo,
132: MAXPATHLEN);
133:
134: l = snprintf(entry, MAXPATHLEN, "%s/%s", repo,
135: cf->file_path);
136:
137: cvs_mkadmin(cf->file_path, current_cvsroot->cr_dir,
138: entry);
139:
140: xfree(repo);
141: xfree(entry);
142:
143: entry = xmalloc(CVS_ENT_MAXLINELEN);
144: l = snprintf(entry, CVS_ENT_MAXLINELEN,
145: "D/%s/////", cf->file_name);
146: entlist = cvs_ent_open(cf->file_wd);
147: cvs_ent_add(entlist, entry);
148: cvs_ent_close(entlist, ENT_SYNC);
149:
150: cvs_printf("Directory %s added to the repository\n",
151: cf->file_rpath);
152: }
153: }
154:
155: cf->file_status = FILE_SKIP;
156: xfree(entry);
157: }
1.3 jfb 158:
1.45 joris 159: static void
160: add_file(struct cvs_file *cf)
161: {
162: int l;
163: int stop;
164: char *entry, revbuf[16];
165: CVSENTRIES *entlist;
1.10 xsa 166:
1.44 joris 167: if (cf->file_rcs != NULL)
168: rcsnum_tostr(cf->file_rcs->rf_head, revbuf, sizeof(revbuf));
169:
170: stop = 0;
1.43 joris 171: switch (cf->file_status) {
172: case FILE_ADDED:
173: cvs_log(LP_NOTICE, "%s has already been entered",
174: cf->file_path);
1.44 joris 175: stop = 1;
176: break;
177: case FILE_UPTODATE:
178: if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 0) {
179: cvs_log(LP_NOTICE, "%s already exists, with version "
180: "number %s", cf->file_path, revbuf);
181: stop = 1;
182: }
1.43 joris 183: break;
184: case FILE_UNKNOWN:
1.44 joris 185: if (cf->file_rcs != NULL && cf->file_rcs->rf_dead == 1) {
186: cvs_log(LP_NOTICE, "re-adding file %s "
187: "(instead of dead revision %s)",
188: cf->file_path, revbuf);
189: } else {
190: cvs_log(LP_NOTICE, "scheduling file '%s' for addition",
191: cf->file_path);
192: }
1.43 joris 193: break;
194: default:
195: break;
1.1 jfb 196: }
1.44 joris 197:
198: if (stop == 1)
199: return;
200:
201: entry = xmalloc(CVS_ENT_MAXLINELEN);
202: l = snprintf(entry, CVS_ENT_MAXLINELEN, "/%s/0/Initial %s//",
203: cf->file_name, cf->file_name);
204:
205: entlist = cvs_ent_open(cf->file_wd);
206: cvs_ent_add(entlist, entry);
207: cvs_ent_close(entlist, ENT_SYNC);
208:
209: xfree(entry);
210:
211: cvs_log(LP_NOTICE, "use commit to add this file permanently");
1.1 jfb 212: }