6 /* Rename a file, copying it if necessary. */
22 say2("Moving %s to stdout.\n", from
);
24 fromfd
= open(from
, 0);
26 fatal2("patch: internal error, can't reopen %s\n", from
);
27 while ((i
=read(fromfd
, buf
, sizeof buf
)) > 0)
28 if (write(1, buf
, i
) != i
)
29 fatal1("patch: write failed\n");
35 Strcpy (bakname
, origprae
);
39 Strcat(bakname
, origext
?origext
:ORIGEXT
);
41 if (stat(to
, &filestat
) >= 0) { /* output file exists */
42 dev_t to_device
= filestat
.st_dev
;
43 ino_t to_inode
= filestat
.st_ino
;
44 char *simplename
= bakname
;
46 for (s
=bakname
; *s
; s
++) {
50 /* find a backup name that is not the same file */
51 while (stat(bakname
, &filestat
) >= 0 &&
52 to_device
== filestat
.st_dev
&& to_inode
== filestat
.st_ino
) {
53 for (s
=simplename
; *s
&& !islower(*s
); s
++) ;
57 Strcpy(simplename
, simplename
+1);
59 while (unlink(bakname
) >= 0) ; /* while() is for benefit of Eunice */
62 say3("Moving %s to %s.\n", to
, bakname
);
64 if (link(to
, bakname
) < 0) {
65 say3("patch: can't backup %s, output is in %s\n",
69 while (unlink(to
) >= 0) ;
73 say3("Moving %s to %s.\n", from
, to
);
75 if (link(from
, to
) < 0) { /* different file system? */
78 tofd
= creat(to
, 0666);
80 say3("patch: can't create %s, output is in %s.\n",
84 fromfd
= open(from
, 0);
86 fatal2("patch: internal error, can't reopen %s\n", from
);
87 while ((i
=read(fromfd
, buf
, sizeof buf
)) > 0)
88 if (write(tofd
, buf
, i
) != i
)
89 fatal1("patch: write failed\n");
107 tofd
= creat(to
, 0666);
109 fatal2("patch: can't create %s.\n", to
);
110 fromfd
= open(from
, 0);
112 fatal2("patch: internal error, can't reopen %s\n", from
);
113 while ((i
=read(fromfd
, buf
, sizeof buf
)) > 0)
114 if (write(tofd
, buf
, i
) != i
)
115 fatal2("patch: write (%s) failed\n", to
);
120 /* Allocate a unique area for a string. */
133 rv
= (char *)malloc((MEM
) (t
- s
));
138 fatal1("patch: out of memory (savestr)\n");
147 #if defined(lint) && defined(CANVARARG)
150 say(pat
) char *pat
; { ; }
152 fatal(pat
) char *pat
; { ; }
154 ask(pat
) char *pat
; { ; }
158 /* Vanilla terminal output (buffered). */
161 say(pat
,arg1
,arg2
,arg3
)
165 fprintf(stderr
, pat
, arg1
, arg2
, arg3
);
169 /* Terminal output, pun intended. */
172 fatal(pat
,arg1
,arg2
,arg3
)
176 say(pat
, arg1
, arg2
, arg3
);
180 /* Get a response from the user, somehow or other. */
183 ask(pat
,arg1
,arg2
,arg3
)
189 bool tty2
= isatty(2);
191 Sprintf(buf
, pat
, arg1
, arg2
, arg3
);
193 write(2, buf
, strlen(buf
));
194 if (tty2
) { /* might be redirected to a file */
195 r
= read(2, buf
, sizeof buf
);
197 else if (isatty(1)) { /* this may be new file output */
199 write(1, buf
, strlen(buf
));
200 r
= read(1, buf
, sizeof buf
);
202 else if ((ttyfd
= open("/dev/tty", 2)) >= 0 && isatty(ttyfd
)) {
203 /* might be deleted or unwriteable */
204 write(ttyfd
, buf
, strlen(buf
));
205 r
= read(ttyfd
, buf
, sizeof buf
);
208 else if (isatty(0)) { /* this is probably patch input */
210 write(0, buf
, strlen(buf
));
211 r
= read(0, buf
, sizeof buf
);
213 else { /* no terminal at all--default it */
226 /* How to handle certain events when not in a critical region. */
234 static void (*hupval
)(),(*intval
)();
236 static int (*hupval
)(),(*intval
)();
240 hupval
= signal(SIGHUP
, SIG_IGN
);
241 if (hupval
!= SIG_IGN
)
245 hupval
= (int(*)())my_exit
;
247 intval
= signal(SIGINT
, SIG_IGN
);
248 if (intval
!= SIG_IGN
)
252 intval
= (int(*)())my_exit
;
255 Signal(SIGHUP
, hupval
);
256 Signal(SIGINT
, intval
);
260 /* How to handle certain events when in a critical region. */
266 Signal(SIGHUP
, SIG_IGN
);
267 Signal(SIGINT
, SIG_IGN
);
271 /* Make sure we'll have the directories to create a file. */
274 makedirs(filename
,striplast
)
279 Reg2
char *s
= tmpbuf
;
285 if (*filename
== '/') {
300 strcpy(buf
, "mkdir");
302 for (i
=0; i
<=dirvp
; i
++) {
311 /* Make filenames more reasonable. */
314 fetchname(at
,strip_leading
,assume_exists
)
327 for (t
=s
; isspace(*t
); t
++) ;
331 say4("fetchname %s %d %d\n",name
,strip_leading
,assume_exists
);
333 if (strnEQ(name
, "/dev/null", 9)) /* so files can be created by diffing */
334 return Nullch
; /* against /dev/null. */
335 for (; *t
&& !isspace(*t
); t
++)
337 if (--strip_leading
>= 0)
340 if (name
!= s
&& *s
!= '/') {
342 if (stat(s
, &filestat
) && filestat
.st_mode
& S_IFDIR
) {
347 name
= savestr(name
);
348 Sprintf(tmpbuf
, "RCS/%s", name
);
350 if (stat(name
, &filestat
) < 0 && !assume_exists
) {
351 Strcat(tmpbuf
, RCSSUFFIX
);
352 if (stat(tmpbuf
, &filestat
) < 0 && stat(tmpbuf
+4, &filestat
) < 0) {
353 Sprintf(tmpbuf
, "SCCS/%s%s", SCCSPREFIX
, name
);
354 if (stat(tmpbuf
, &filestat
) < 0 && stat(tmpbuf
+5, &filestat
) < 0) {