1 /* co - check out Author: Peter S. Housel 12/24/87 */
11 #define SUFFIX ",S" /* svc indicator */
12 #define SVCDIR "SVC" /* svc postfix indicator */
14 #define LINELEN 256 /* maximum line length */
17 #define PATHLEN MAXPATHLEN
19 #define PATHLEN 128 /* buffer length for filenames */
22 char file
[PATHLEN
]; /* file to be checked in */
23 char svc
[PATHLEN
]; /* filename for svc file */
24 char newsvc
[PATHLEN
]; /* new copy of SVC file */
25 char line
[LINELEN
]; /* temporary line buffer */
26 char *p
; /* scratch character pointer */
28 FILE *svcfp
; /* svc file */
29 int rev
; /* old revision number */
30 int lastrev
, lockrev
; /* latest file revision, lock into */
31 int status
; /* wait() buffer */
32 int svclock
; /* lock the SVC file */
33 struct stat stb
; /* stat() buffer */
34 char *base
; /* basename of file */
36 char difftemp
[PATHLEN
]; /* extract() fix/patch input */
38 int main(int argc
, char **argv
);
39 void fname(char *src
, char *dst
);
40 void svcname(char *src
, char *dst
);
41 void extract(char *script
, char *out
, int rev
);
42 char *basename(char *name
);
52 setbuf(stderr
, errbuf
);
56 while (++argv
, --argc
) {
57 if ('-' == (*argv
)[0]) {
58 if ('r' == (*argv
)[1]) {
62 fprintf(stderr
, "Illegal revision number\n");
65 } else if ('l' == (*argv
)[1])
68 fprintf(stderr
, "co: illegal option -%c\n", (*argv
)[1]);
76 fprintf(stderr
, "co: bad number of files arguments\n");
82 fprintf(stderr
, "%s -> %s\n", svc
, base
= basename(file
));
84 if (NULL
== (svcfp
= fopen(svc
, "r"))) {
85 perror("co: can't read SVC file");
88 if (1 != fscanf(svcfp
, "# %d", &lastrev
) || lastrev
< 1) {
89 fprintf(stderr
, "co: illegal SVC file format\n");
94 if (stat(base
, &stb
) >= 0 && (stb
.st_mode
& 0222)) {
95 fprintf(stderr
, "Writable %s exists - overwrite (n/y)? ", base
);
97 fprintf(stderr
, "Checkout aborted\n");
101 if (strlen(base
)) unlink(base
);
102 if (0 == rev
) rev
= lastrev
;
103 fprintf(stderr
, "Checking out revision %d", rev
);
104 extract(svc
, base
, rev
);
107 lockrev
= lastrev
+ 1;
108 fprintf(stderr
, "; Locking into revision %d\n", lockrev
);
109 if (stat(svc
, &stb
) < 0 || chmod(svc
, stb
.st_mode
| 0200) < 0)
110 perror("co: can't chmod SVC file");
112 if (stat(base
, &stb
) < 0 || chmod(base
, stb
.st_mode
| 0200) < 0)
113 perror("co: can't chmod source file");
115 if (NULL
== (svcfp
= fopen(svc
, "a"))
116 || (fprintf(svcfp
, "#***SVCLOCK*** %s %d\n", whoami(), lockrev
), ferror(svcfp
))) {
117 fprintf(stderr
, "co: can't lock %s\n", svc
);
120 if (stat(svc
, &stb
) < 0 || chmod(svc
, stb
.st_mode
& 0555))
121 perror("co: can't chmod SVC file");
124 if (stat(base
, &stb
) < 0 || chmod(base
, stb
.st_mode
& 0555))
125 perror("co: can't chmod source file");
137 p
= &dst
[strlen(src
) - strlen(SUFFIX
)];
138 if (!strcmp(p
, SUFFIX
)) *p
= '\0';
141 void svcname(src
, dst
)
149 if (0 != access(dst
, 4)) {
150 char dirname
[PATHLEN
];
151 if (NULL
!= (p
= strrchr(src
, '/')))
152 strncpy(dirname
, src
, (size_t)(p
- src
) + 1);
155 strcat(dirname
, SVCDIR
);
157 if (0 == access(dirname
, 1)) {
158 strcpy(dst
, dirname
);
169 void extract(script
, out
, rev
)
177 sprintf(difftemp
, "Fix.%s", out
);
179 svcfp
= fopen(script
, "r");
180 fgets(line
, LINELEN
, svcfp
); /* skip '# rev' line */
181 fgets(line
, LINELEN
, svcfp
); /* skip 'cat <***MAIN-eof***' line */
183 if (NULL
== (outfp
= fopen(out
, "w"))) {
184 perror("co: can't create output file");
187 while (NULL
!= fgets(line
, LINELEN
, svcfp
) &&
188 strcmp(line
, "***MAIN-eof***\n"))
193 while (NULL
!= fgets(line
, LINELEN
, svcfp
)) {
194 if (!strncmp(line
, "if ", (size_t)3)) {
195 sscanf(line
, "if test $2 -ge %d", &testrev
);
196 if (rev
>= testrev
) {
200 if (NULL
== (outfp
= fopen(difftemp
, "w"))) {
201 perror("co: can't create output file");
204 sprintf(buf
, "***%d-eof***\n", testrev
);
205 while (NULL
!= fgets(line
, LINELEN
, svcfp
) &&
209 } else if (!strncmp(line
, "mv ", (size_t)3)) {
210 sprintf(buf
, "mv Fix.%s %s", out
, out
);
212 } else if (!strncmp(line
, "fix ", (size_t)4)) {
213 sprintf(buf
, "fix %s Fix.%s > New.%s; mv New.%s %s", out
, out
, out
, out
, out
);
215 } else if (!strncmp(line
, "patch ", (size_t)6)) {
216 sprintf(buf
, "patch -n -s %s < Fix.%s; rm -f %s.orig", out
, out
, out
);
218 } else { /* ignore */
231 if (NULL
== (p
= strrchr(name
, '/')))
241 if (NULL
!= (pw
= getpwuid(getuid())))
251 return(NULL
!= fgets(ans
, 10, stdin
)) && ('y' == ans
[0] || 'Y' == ans
[0]);