Commit | Line | Data |
---|---|---|
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 | |
21 | static char rcsid[] = "@(#)checkin.c 1.40 92/03/31"; | |
22 | #endif | |
23 | ||
24 | int | |
25 | Checkin (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 | } |