386BSD 0.1 development
[unix-history] / usr / othersrc / public / cvs-1.3 / src / checkin.c
CommitLineData
fe37a9c9
WJ
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License as
6 * specified in the README file that comes with the CVS 1.3 kit.
7 *
8 * Check In
9 *
10 * Does a very careful checkin of the file "user", and tries not to spoil its
11 * modification time (to avoid needless recompilations). When RCS ID keywords
12 * get expanded on checkout, however, the modification time is updated and
13 * there is no good way to get around this.
14 *
15 * Returns non-zero on error.
16 */
17
18#include "cvs.h"
19
20#ifndef lint
21static char rcsid[] = "@(#)checkin.c 1.40 92/03/31";
22#endif
23
24int
25Checkin (type, file, repository, rcs, rev, tag, message, entries)
26 int type;
27 char *file;
28 char *repository;
29 char *rcs;
30 char *rev;
31 char *tag;
32 char *message;
33 List *entries;
34{
35 char fname[PATH_MAX];
36 Vers_TS *vers;
37
38 (void) printf ("Checking in %s;\n", file);
39 (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
40
41 /*
42 * Move the user file to a backup file, so as to preserve its
43 * modification times, then place a copy back in the original file name
44 * for the checkin and checkout.
45 */
46 if (!noexec)
47 copy_file (file, fname);
48
49 run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI,
50 rev ? "-r" : "", rev ? rev : "");
51 run_args ("-m%s", message);
52 run_arg (rcs);
53
54 switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL))
55 {
56 case 0: /* everything normal */
57
58 /*
59 * The checkin succeeded, so now check the new file back out and
60 * see if it matches exactly with the one we checked in. If it
61 * does, just move the original user file back, thus preserving
62 * the modes; otherwise, we have no recourse but to leave the
63 * newly checkout file as the user file and remove the old
64 * original user file.
65 */
66
67 /* XXX - make sure -k options are used on the co; and tag/date? */
68 run_setup ("%s%s -q %s%s", Rcsbin, RCS_CO,
69 rev ? "-r" : "", rev ? rev : "");
70 run_arg (rcs);
71 (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
72 xchmod (file, 1);
73 if (xcmp (file, fname) == 0)
74 rename_file (fname, file);
75 else
76 (void) unlink_file (fname);
77
78 /*
79 * If we want read-only files, muck the permissions here, before
80 * getting the file time-stamp.
81 */
82 if (cvswrite == FALSE)
83 xchmod (file, 0);
84
85 /* for added files with symbolic tags, need to add the tag too */
86 if (type == 'A' && tag && !isdigit (*tag))
87 {
88 run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, tag, rev);
89 run_arg (rcs);
90 (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
91 }
92
93 /* re-register with the new data */
94 vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL,
95 file, 1, 1, entries, (List *) NULL);
96 if (strcmp (vers->options, "-V4") == 0)
97 vers->options[0] = '\0';
98 Register (entries, file, vers->vn_rcs, vers->ts_user, vers->options,
99 vers->tag, vers->date);
100 history_write (type, (char *) 0, vers->vn_rcs, file, repository);
101 freevers_ts (&vers);
102 break;
103
104 case -1: /* fork failed */
105 if (!noexec)
106 error (1, errno, "could not check in %s -- fork failed", file);
107 return (1);
108
109 default: /* ci failed */
110
111 /*
112 * The checkin failed, for some unknown reason, so we restore the
113 * original user file, print an error, and return an error
114 */
115 if (!noexec)
116 {
117 rename_file (fname, file);
118 error (0, 0, "could not check in %s", file);
119 }
120 return (1);
121 }
122
123 /*
124 * When checking in a specific revision, we may have locked the wrong
125 * branch, so to be sure, we do an extra unlock here before
126 * returning.
127 */
128 if (rev)
129 {
130 run_setup ("%s%s -q -u", Rcsbin, RCS);
131 run_arg (rcs);
132 (void) run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL);
133 }
134 return (0);
135}