1 /* utility functions for `patch' */ 2 3 /* $Id: util.c,v 1.24 1997/07/10 08:16:12 eggert Exp $ */ 4 5 /* 6 Copyright 1986 Larry Wall 7 Copyright 1992, 1993, 1997 Free Software Foundation, Inc. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2, or (at your option) 12 any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; see the file COPYING. 21 If not, write to the Free Software Foundation, 22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 */ 24 25 #define XTERN extern 26 #include <common.h> 27 #include <backupfile.h> 28 #include <quotearg.h> 29 #include <version.h> 30 #undef XTERN 31 #define XTERN 32 #include <util.h> 33 34 #include <maketime.h> 35 #include <partime.h> 36 37 #include <signal.h> 38 #if !defined SIGCHLD && defined SIGCLD 39 #define SIGCHLD SIGCLD 40 #endif 41 #if ! HAVE_RAISE 42 # define raise(sig) kill (getpid (), sig) 43 #endif 44 45 #ifdef __STDC__ 46 # include <stdarg.h> 47 # define vararg_start va_start 48 #else 49 # define vararg_start(ap,p) va_start (ap) 50 # if HAVE_VARARGS_H 51 # include <varargs.h> 52 # else 53 typedef char *va_list; 54 # define va_dcl int va_alist; 55 # define va_start(ap) ((ap) = (va_list) &va_alist) 56 # define va_arg(ap, t) (((t *) ((ap) += sizeof (t))) [-1]) 57 # define va_end(ap) 58 # endif 59 #endif 60 61 static void makedirs PARAMS ((char *)); 62 63 /* Move a file FROM to TO, renaming it if possible and copying it if necessary. 64 If we must create TO, use MODE to create it. 65 If FROM is null, remove TO (ignoring FROMSTAT). 66 Back up TO if BACKUP is nonzero. */ 67 68 #ifdef __STDC__ 69 /* If mode_t doesn't promote to itself, we can't use old-style definition. */ 70 void 71 move_file (char const *from, char *to, mode_t mode, int backup) 72 #else 73 void 74 move_file (from, to, mode, backup) 75 char const *from; 76 char *to; 77 mode_t mode; 78 int backup; 79 #endif 80 { 81 struct stat to_st; 82 int to_errno = ! backup ? -1 : stat (to, &to_st) == 0 ? 0 : errno; 83 84 if (backup) 85 { 86 int try_makedirs_errno = 0; 87 char *bakname; 88 89 if (origprae || origbase) 90 { 91 char const *p = origprae ? origprae : ""; 92 char const *b = origbase ? origbase : ""; 93 char const *o = base_name (to); 94 size_t plen = strlen (p); 95 size_t tlen = o - to; 96 size_t blen = strlen (b); 97 size_t osize = strlen (o) + 1; 98 bakname = xmalloc (plen + tlen + blen + osize); 99 memcpy (bakname, p, plen); 100 memcpy (bakname + plen, to, tlen); 101 memcpy (bakname + plen + tlen, b, blen); 102 memcpy (bakname + plen + tlen + blen, o, osize); 103 for (p += FILESYSTEM_PREFIX_LEN (p); *p; p++) 104 if (ISSLASH (*p)) 105 { 106 try_makedirs_errno = ENOENT; 107 break; 108 } 109 } 110 else 111 { 112 bakname = find_backup_file_name (to); 113 if (!bakname) 114 memory_fatal (); 115 } 116 117 if (to_errno) 118 { 119 int fd; 120 if (debug & 4) 121 say ("creating empty unreadable file `%s'\n", bakname); 122 try_makedirs_errno = ENOENT; 123 unlink (bakname); 124 while ((fd = creat (bakname, 0)) < 0) 125 { 126 if (errno != try_makedirs_errno) 127 pfatal ("can't create file `%s'", bakname); 128 makedirs (bakname); 129 try_makedirs_errno = 0; 130 } 131 if (close (fd) != 0) 132 pfatal ("can't close `%s'", bakname); 133 } 134 else 135 { 136 if (debug & 4) 137 say ("renaming `%s' to `%s'\n", to, bakname); 138 while (rename (to, bakname) != 0) 139 { 140 if (errno != try_makedirs_errno) 141 pfatal ("can't rename `%s' to `%s'", to, bakname); 142 makedirs (bakname); 143 try_makedirs_errno = 0; 144 } 145 } 146 147 free (bakname); 148 } 149 150 if (from) 151 { 152 if (debug & 4) 153 say ("renaming `%s' to `%s'\n", from, to); 154 155 if (rename (from, to) != 0) 156 { 157 int to_dir_known_to_exist = 0; 158 159 if (errno == ENOENT 160 && (to_errno == -1 || to_errno == ENOENT)) 161 { 162 makedirs (to); 163 to_dir_known_to_exist = 1; 164 if (rename (from, to) == 0) 165 return; 166 } 167 168 if (errno == EXDEV) 169 { 170 if (! backup) 171 { 172 if (unlink (to) == 0) 173 to_dir_known_to_exist = 1; 174 else if (errno != ENOENT) 175 pfatal ("can't remove `%s'", to); 176 } 177 if (! to_dir_known_to_exist) 178 makedirs (to); 179 copy_file (from, to, mode); 180 return; 181 } 182 183 pfatal ("can't rename `%s' to `%s'", from, to); 184 } 185 } 186 else if (! backup) 187 { 188 if (debug & 4) 189 say ("removing `%s'\n", to); 190 if (unlink (to) != 0) 191 pfatal ("can't remove `%s'", to); 192 } 193 } 194 195 /* Create FILE with OPEN_FLAGS, and with MODE adjusted so that 196 we can read and write the file and that the file is not executable. 197 Return the file descriptor. */ 198 #ifdef __STDC__ 199 /* If mode_t doesn't promote to itself, we can't use old-style definition. */ 200 int 201 create_file (char const *file, int open_flags, mode_t mode) 202 #else 203 int 204 create_file (file, open_flags, mode) 205 char const *file; 206 int open_flags; 207 mode_t mode; 208 #endif 209 { 210 int fd; 211 mode |= S_IRUSR | S_IWUSR; 212 mode &= ~ (S_IXUSR | S_IXGRP | S_IXOTH); 213 if (! (O_CREAT && O_TRUNC)) 214 close (creat (file, mode)); 215 fd = open (file, O_CREAT | O_TRUNC | open_flags, mode); 216 if (fd < 0) 217 pfatal ("can't create `%s'", file); 218 return fd; 219 } 220 221 /* Copy a file. */ 222 223 #ifdef __STDC__ 224 /* If mode_t doesn't promote to itself, we can't use old-style definition. */ 225 void 226 copy_file (char const *from, char const *to, mode_t mode) 227 #else 228 void 229 copy_file (from, to, mode) 230 char const *from; 231 char const *to; 232 mode_t mode; 233 #endif 234 { 235 int tofd; 236 int fromfd; 237 size_t i; 238 239 if ((fromfd = open (from, O_RDONLY | O_BINARY)) < 0) 240 pfatal ("can't reopen `%s'", from); 241 tofd = create_file (to, O_WRONLY | O_BINARY, mode); 242 while ((i = read (fromfd, buf, bufsize)) != 0) 243 { 244 if (i == -1) 245 read_fatal (); 246 if (write (tofd, buf, i) != i) 247 write_fatal (); 248 } 249 if (close (fromfd) != 0) 250 read_fatal (); 251 if (close (tofd) != 0) 252 write_fatal (); 253 } 254 255 static char const DEV_NULL[] = NULL_DEVICE; 256 257 static char const SCCSPREFIX[] = "s."; 258 static char const GET[] = "get "; 259 static char const GET_LOCKED[] = "get -e "; 260 static char const SCCSDIFF1[] = "get -p "; 261 static char const SCCSDIFF2[] = "|diff - %s"; 262 263 static char const RCSSUFFIX[] = ",v"; 264 static char const CHECKOUT[] = "co %s"; 265 static char const CHECKOUT_LOCKED[] = "co -l %s"; 266 static char const RCSDIFF1[] = "rcsdiff %s"; 267 268 /* Return "RCS" if FILENAME is controlled by RCS, 269 "SCCS" if it is controlled by SCCS, and 0 otherwise. 270 READONLY is nonzero if we desire only readonly access to FILENAME. 271 FILESTAT describes FILENAME's status or is 0 if FILENAME does not exist. 272 If successful and if GETBUF is nonzero, set *GETBUF to a command 273 that gets the file; similarly for DIFFBUF and a command to diff the file. 274 *GETBUF and *DIFFBUF must be freed by the caller. */ 275 char const * 276 version_controller (filename, readonly, filestat, getbuf, diffbuf) 277 char const *filename; 278 int readonly; 279 struct stat const *filestat; 280 char **getbuf; 281 char **diffbuf; 282 { 283 struct stat cstat; 284 char const *filebase = base_name (filename); 285 char const *dotslash = *filename == '-' ? "./" : ""; 286 size_t dir_len = filebase - filename; 287 size_t filenamelen = strlen (filename); 288 size_t maxfixlen = sizeof "SCCS/" - 1 + sizeof SCCSPREFIX - 1; 289 size_t maxtrysize = filenamelen + maxfixlen + 1; 290 size_t quotelen = quote_system_arg (0, filename); 291 size_t maxgetsize = sizeof GET_LOCKED + quotelen + maxfixlen; 292 size_t maxdiffsize = 293 (sizeof SCCSDIFF1 + sizeof SCCSDIFF2 + sizeof DEV_NULL - 1 294 + 2 * quotelen + maxfixlen); 295 char *trybuf = xmalloc (maxtrysize); 296 char const *r = 0; 297 298 strcpy (trybuf, filename); 299 300 #define try1(f,a1) (sprintf (trybuf + dir_len, f, a1), stat (trybuf, &cstat) == 0) 301 #define try2(f,a1,a2) (sprintf (trybuf + dir_len, f, a1,a2), stat (trybuf, &cstat) == 0) 302 303 /* Check that RCS file is not working file. 304 Some hosts don't report file name length errors. */ 305 306 if ((try2 ("RCS/%s%s", filebase, RCSSUFFIX) 307 || try1 ("RCS/%s", filebase) 308 || try2 ("%s%s", filebase, RCSSUFFIX)) 309 && ! (filestat 310 && filestat->st_dev == cstat.st_dev 311 && filestat->st_ino == cstat.st_ino)) 312 { 313 if (getbuf) 314 { 315 char *p = *getbuf = xmalloc (maxgetsize); 316 sprintf (p, readonly ? CHECKOUT : CHECKOUT_LOCKED, dotslash); 317 p += strlen (p); 318 p += quote_system_arg (p, filename); 319 *p = '\0'; 320 } 321 322 if (diffbuf) 323 { 324 char *p = *diffbuf = xmalloc (maxdiffsize); 325 sprintf (p, RCSDIFF1, dotslash); 326 p += strlen (p); 327 p += quote_system_arg (p, filename); 328 *p++ = '>'; 329 strcpy (p, DEV_NULL); 330 } 331 332 r = "RCS"; 333 } 334 else if (try2 ("SCCS/%s%s", SCCSPREFIX, filebase) 335 || try2 ("%s%s", SCCSPREFIX, filebase)) 336 { 337 if (getbuf) 338 { 339 char *p = *getbuf = xmalloc (maxgetsize); 340 sprintf (p, readonly ? GET : GET_LOCKED); 341 p += strlen (p); 342 p += quote_system_arg (p, trybuf); 343 *p = '\0'; 344 } 345 346 if (diffbuf) 347 { 348 char *p = *diffbuf = xmalloc (maxdiffsize); 349 strcpy (p, SCCSDIFF1); 350 p += sizeof SCCSDIFF1 - 1; 351 p += quote_system_arg (p, trybuf); 352 sprintf (p, SCCSDIFF2, dotslash); 353 p += strlen (p); 354 p += quote_system_arg (p, filename); 355 *p++ = '>'; 356 strcpy (p, DEV_NULL); 357 } 358 359 r = "SCCS"; 360 } 361 362 free (trybuf); 363 return r; 364 } 365 366 /* Get FILENAME from version control system CS. The file already exists if 367 EXISTS is nonzero. Only readonly access is needed if READONLY is nonzero. 368 Use the command GETBUF to actually get the named file. 369 Store the resulting file status into *FILESTAT. 370 Return nonzero if successful. */ 371 int 372 version_get (filename, cs, exists, readonly, getbuf, filestat) 373 char const *filename; 374 char const *cs; 375 int exists; 376 int readonly; 377 char const *getbuf; 378 struct stat *filestat; 379 { 380 if (patch_get < 0) 381 { 382 ask ("Get file `%s' from %s%s? [y] ", filename, 383 cs, readonly ? "" : " with lock"); 384 if (*buf == 'n') 385 return 0; 386 } 387 388 if (dry_run) 389 { 390 if (! exists) 391 fatal ("can't do dry run on nonexistent version-controlled file `%s'; invoke `%s' and try again", 392 filename, getbuf); 393 } 394 else 395 { 396 if (verbosity == VERBOSE) 397 say ("Getting file `%s' from %s%s...\n", filename, 398 cs, readonly ? "" : " with lock"); 399 if (systemic (getbuf) != 0) 400 fatal ("can't get file `%s' from %s", filename, cs); 401 if (stat (filename, filestat) != 0) 402 pfatal ("%s", filename); 403 } 404 405 return 1; 406 } 407 408 /* Allocate a unique area for a string. */ 409 410 char * 411 savebuf (s, size) 412 register char const *s; 413 register size_t size; 414 { 415 register char *rv; 416 417 assert (s && size); 418 rv = malloc (size); 419 420 if (! rv) 421 { 422 if (! using_plan_a) 423 memory_fatal (); 424 } 425 else 426 memcpy (rv, s, size); 427 428 return rv; 429 } 430 431 char * 432 savestr(s) 433 char const *s; 434 { 435 return savebuf (s, strlen (s) + 1); 436 } 437 438 void 439 remove_prefix (p, prefixlen) 440 char *p; 441 size_t prefixlen; 442 { 443 char const *s = p + prefixlen; 444 while ((*p++ = *s++)) 445 continue; 446 } 447 448 #if !HAVE_VPRINTF 449 #define vfprintf my_vfprintf 450 static int vfprintf PARAMS ((FILE *, char const *, va_list)); 451 static int 452 vfprintf (stream, format, args) 453 FILE *stream; 454 char const *format; 455 va_list args; 456 { 457 #if !HAVE_DOPRNT && HAVE__DOPRINTF 458 # define _doprnt _doprintf 459 #endif 460 #if HAVE_DOPRNT || HAVE__DOPRINTF 461 _doprnt (format, args, stream); 462 return ferror (stream) ? -1 : 0; 463 #else 464 int *a = (int *) args; 465 return fprintf (stream, format, 466 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); 467 #endif 468 } 469 #endif /* !HAVE_VPRINTF */ 470 471 /* Terminal output, pun intended. */ 472 473 #ifdef __STDC__ 474 void 475 fatal (char const *format, ...) 476 #else 477 /*VARARGS1*/ void 478 fatal (format, va_alist) 479 char const *format; 480 va_dcl 481 #endif 482 { 483 va_list args; 484 fprintf (stderr, "%s: **** ", program_name); 485 vararg_start (args, format); 486 vfprintf (stderr, format, args); 487 va_end (args); 488 putc ('\n', stderr); 489 fflush (stderr); 490 fatal_exit (0); 491 } 492 493 void 494 memory_fatal () 495 { 496 fatal ("out of memory"); 497 } 498 499 void 500 read_fatal () 501 { 502 pfatal ("read error"); 503 } 504 505 void 506 write_fatal () 507 { 508 pfatal ("write error"); 509 } 510 511 /* Say something from patch, something from the system, then silence . . . */ 512 513 #ifdef __STDC__ 514 void 515 pfatal (char const *format, ...) 516 #else 517 /*VARARGS1*/ void 518 pfatal (format, va_alist) 519 char const *format; 520 va_dcl 521 #endif 522 { 523 int errnum = errno; 524 va_list args; 525 fprintf (stderr, "%s: **** ", program_name); 526 vararg_start (args, format); 527 vfprintf (stderr, format, args); 528 va_end (args); 529 fflush (stderr); /* perror bypasses stdio on some hosts. */ 530 errno = errnum; 531 perror (" "); 532 fflush (stderr); 533 fatal_exit (0); 534 } 535 536 /* Tell the user something. */ 537 538 #ifdef __STDC__ 539 void 540 say (char const *format, ...) 541 #else 542 /*VARARGS1*/ void 543 say (format, va_alist) 544 char const *format; 545 va_dcl 546 #endif 547 { 548 va_list args; 549 vararg_start (args, format); 550 vfprintf (stdout, format, args); 551 va_end (args); 552 fflush (stdout); 553 } 554 555 /* Get a response from the user, somehow or other. */ 556 557 #ifdef __STDC__ 558 void 559 ask (char const *format, ...) 560 #else 561 /*VARARGS1*/ void 562 ask (format, va_alist) 563 char const *format; 564 va_dcl 565 #endif 566 { 567 static int ttyfd = -2; 568 int r; 569 va_list args; 570 571 vararg_start (args, format); 572 vfprintf (stdout, format, args); 573 va_end (args); 574 fflush (stdout); 575 576 if (ttyfd == -2) 577 { 578 /* If standard output is not a tty, don't bother opening /dev/tty, 579 since it's unlikely that stdout will be seen by the tty user. 580 The isatty test also works around a bug in GNU Emacs 19.34 under Linux 581 which makes a call-process `patch' hang when it reads from /dev/tty. 582 POSIX.2 requires that we read /dev/tty, though. */ 583 ttyfd = (posixly_correct || isatty (STDOUT_FILENO) 584 ? open (TTY_DEVICE, O_RDONLY) 585 : -1); 586 } 587 588 if (ttyfd < 0) 589 { 590 /* No terminal at all -- default it. */ 591 printf ("\n"); 592 buf[0] = '\n'; 593 buf[1] = '\0'; 594 } 595 else 596 { 597 size_t s = 0; 598 while ((r = read (ttyfd, buf + s, bufsize - 1 - s)) == bufsize - 1 - s 599 && buf[bufsize - 2] != '\n') 600 { 601 s = bufsize - 1; 602 bufsize *= 2; 603 buf = realloc (buf, bufsize); 604 if (!buf) 605 memory_fatal (); 606 } 607 if (r == 0) 608 printf ("EOF\n"); 609 else if (r < 0) 610 { 611 perror ("tty read"); 612 fflush (stderr); 613 close (ttyfd); 614 ttyfd = -1; 615 r = 0; 616 } 617 buf[s + r] = '\0'; 618 } 619 } 620 621 /* Return nonzero if it OK to reverse a patch. */ 622 623 #ifdef __STDC__ 624 int 625 ok_to_reverse (char const *format, ...) 626 #else 627 ok_to_reverse (format, va_alist) 628 char const *format; 629 va_dcl 630 #endif 631 { 632 int r = 0; 633 634 if (noreverse || ! (force && verbosity == SILENT)) 635 { 636 va_list args; 637 vararg_start (args, format); 638 vfprintf (stdout, format, args); 639 va_end (args); 640 } 641 642 if (noreverse) 643 { 644 printf (" Skipping patch.\n"); 645 skip_rest_of_patch = TRUE; 646 r = 0; 647 } 648 else if (force) 649 { 650 if (verbosity != SILENT) 651 printf (" Applying it anyway.\n"); 652 r = 0; 653 } 654 else if (batch) 655 { 656 say (reverse ? " Ignoring -R.\n" : " Assuming -R.\n"); 657 r = 1; 658 } 659 else 660 { 661 ask (reverse ? " Ignore -R? [n] " : " Assume -R? [n] "); 662 r = *buf == 'y'; 663 if (! r) 664 { 665 ask ("Apply anyway? [n] "); 666 if (*buf != 'y') 667 { 668 if (verbosity != SILENT) 669 say ("Skipping patch.\n"); 670 skip_rest_of_patch = TRUE; 671 } 672 } 673 } 674 675 return r; 676 } 677 678 /* How to handle certain events when not in a critical region. */ 679 680 #define NUM_SIGS (sizeof (sigs) / sizeof (*sigs)) 681 static int const sigs[] = { 682 #ifdef SIGHUP 683 SIGHUP, 684 #endif 685 #ifdef SIGPIPE 686 SIGPIPE, 687 #endif 688 #ifdef SIGTERM 689 SIGTERM, 690 #endif 691 #ifdef SIGXCPU 692 SIGXCPU, 693 #endif 694 #ifdef SIGXFSZ 695 SIGXFSZ, 696 #endif 697 SIGINT 698 }; 699 700 #if !HAVE_SIGPROCMASK 701 #define sigset_t int 702 #define sigemptyset(s) (*(s) = 0) 703 #ifndef sigmask 704 #define sigmask(sig) (1 << ((sig) - 1)) 705 #endif 706 #define sigaddset(s, sig) (*(s) |= sigmask (sig)) 707 #define sigismember(s, sig) ((*(s) & sigmask (sig)) != 0) 708 #ifndef SIG_BLOCK 709 #define SIG_BLOCK 0 710 #endif 711 #ifndef SIG_UNBLOCK 712 #define SIG_UNBLOCK (SIG_BLOCK + 1) 713 #endif 714 #ifndef SIG_SETMASK 715 #define SIG_SETMASK (SIG_BLOCK + 2) 716 #endif 717 #define sigprocmask(how, n, o) \ 718 ((how) == SIG_BLOCK \ 719 ? ((o) ? *(o) = sigblock (*(n)) : sigblock (*(n))) \ 720 : (how) == SIG_UNBLOCK \ 721 ? sigsetmask (((o) ? *(o) = sigblock (0) : sigblock (0)) & ~*(n)) \ 722 : (o ? *(o) = sigsetmask (*(n)) : sigsetmask (*(n)))) 723 #if !HAVE_SIGSETMASK 724 #define sigblock(mask) 0 725 #define sigsetmask(mask) 0 726 #endif 727 #endif 728 729 static sigset_t initial_signal_mask; 730 static sigset_t signals_to_block; 731 732 #if ! HAVE_SIGACTION 733 static RETSIGTYPE fatal_exit_handler PARAMS ((int)) __attribute__ ((noreturn)); 734 static RETSIGTYPE 735 fatal_exit_handler (sig) 736 int sig; 737 { 738 signal (sig, SIG_IGN); 739 fatal_exit (sig); 740 } 741 #endif 742 743 void 744 set_signals(reset) 745 int reset; 746 { 747 int i; 748 #if HAVE_SIGACTION 749 struct sigaction initial_act, fatal_act; 750 fatal_act.sa_handler = fatal_exit; 751 sigemptyset (&fatal_act.sa_mask); 752 fatal_act.sa_flags = 0; 753 #define setup_handler(sig) sigaction (sig, &fatal_act, (struct sigaction *) 0) 754 #else 755 #define setup_handler(sig) signal (sig, fatal_exit_handler) 756 #endif 757 758 if (!reset) 759 { 760 #ifdef SIGCHLD 761 /* System V fork+wait does not work if SIGCHLD is ignored. */ 762 signal (SIGCHLD, SIG_DFL); 763 #endif 764 sigemptyset (&signals_to_block); 765 for (i = 0; i < NUM_SIGS; i++) 766 { 767 int ignoring_signal; 768 #if HAVE_SIGACTION 769 if (sigaction (sigs[i], (struct sigaction *) 0, &initial_act) != 0) 770 continue; 771 ignoring_signal = initial_act.sa_handler == SIG_IGN; 772 #else 773 ignoring_signal = signal (sigs[i], SIG_IGN) == SIG_IGN; 774 #endif 775 if (! ignoring_signal) 776 { 777 sigaddset (&signals_to_block, sigs[i]); 778 setup_handler (sigs[i]); 779 } 780 } 781 } 782 else 783 { 784 /* Undo the effect of ignore_signals. */ 785 #if HAVE_SIGPROCMASK || HAVE_SIGSETMASK 786 sigprocmask (SIG_SETMASK, &initial_signal_mask, (sigset_t *) 0); 787 #else 788 for (i = 0; i < NUM_SIGS; i++) 789 if (sigismember (&signals_to_block, sigs[i])) 790 setup_handler (sigs[i]); 791 #endif 792 } 793 } 794 795 /* How to handle certain events when in a critical region. */ 796 797 void 798 ignore_signals() 799 { 800 #if HAVE_SIGPROCMASK || HAVE_SIGSETMASK 801 sigprocmask (SIG_BLOCK, &signals_to_block, &initial_signal_mask); 802 #else 803 int i; 804 for (i = 0; i < NUM_SIGS; i++) 805 if (sigismember (&signals_to_block, sigs[i])) 806 signal (sigs[i], SIG_IGN); 807 #endif 808 } 809 810 void 811 exit_with_signal (sig) 812 int sig; 813 { 814 sigset_t s; 815 signal (sig, SIG_DFL); 816 sigemptyset (&s); 817 sigaddset (&s, sig); 818 sigprocmask (SIG_UNBLOCK, &s, (sigset_t *) 0); 819 raise (sig); 820 exit (2); 821 } 822 823 int 824 systemic (command) 825 char const *command; 826 { 827 if (debug & 8) 828 say ("+ %s\n", command); 829 fflush (stdout); 830 return system (command); 831 } 832 833 #if !HAVE_MKDIR 834 /* These mkdir and rmdir substitutes are good enough for `patch'; 835 they are not general emulators. */ 836 837 static int doprogram PARAMS ((char const *, char const *)); 838 static int mkdir PARAMS ((char const *, mode_t)); 839 static int rmdir PARAMS ((char const *)); 840 841 static int 842 doprogram (program, arg) 843 char const *program; 844 char const *arg; 845 { 846 int result; 847 static char const DISCARD_OUTPUT[] = " 2>/dev/null"; 848 size_t program_len = strlen (program); 849 char *cmd = xmalloc (program_len + 1 + quote_system_arg (0, arg) 850 + sizeof DISCARD_OUTPUT); 851 char *p = cmd; 852 strcpy (p, program); 853 p += program_len; 854 *p++ = ' '; 855 p += quote_system_arg (p, arg); 856 strcpy (p, DISCARD_OUTPUT); 857 result = systemic (cmd); 858 free (cmd); 859 return result; 860 } 861 862 #ifdef __STDC__ 863 /* If mode_t doesn't promote to itself, we can't use old-style definition. */ 864 static int 865 mkdir (char const *path, mode_t mode) 866 #else 867 static int 868 mkdir (path, mode) 869 char const *path; 870 mode_t mode; /* ignored */ 871 #endif 872 { 873 return doprogram ("mkdir", path); 874 } 875 876 static int 877 rmdir (path) 878 char const *path; 879 { 880 int result = doprogram ("rmdir", path); 881 errno = EEXIST; 882 return result; 883 } 884 #endif 885 886 /* Replace '/' with '\0' in FILENAME if it marks a place that 887 needs testing for the existence of directory. Return the address 888 of the last location replaced, or 0 if none were replaced. */ 889 static char *replace_slashes PARAMS ((char *)); 890 static char * 891 replace_slashes (filename) 892 char *filename; 893 { 894 char *f; 895 char *last_location_replaced = 0; 896 char const *component_start; 897 898 for (f = filename + FILESYSTEM_PREFIX_LEN (filename); ISSLASH (*f); f++) 899 continue; 900 901 component_start = f; 902 903 for (; *f; f++) 904 if (ISSLASH (*f)) 905 { 906 char *slash = f; 907 908 /* Treat multiple slashes as if they were one slash. */ 909 while (ISSLASH (f[1])) 910 f++; 911 912 /* Ignore slashes at the end of the path. */ 913 if (! f[1]) 914 break; 915 916 /* "." and ".." need not be tested. */ 917 if (! (slash - component_start <= 2 918 && component_start[0] == '.' && slash[-1] == '.')) 919 { 920 *slash = '\0'; 921 last_location_replaced = slash; 922 } 923 924 component_start = f + 1; 925 } 926 927 return last_location_replaced; 928 } 929 930 /* Make sure we'll have the directories to create a file. 931 Ignore the last element of `filename'. */ 932 933 static void 934 makedirs (filename) 935 register char *filename; 936 { 937 register char *f; 938 register char *flim = replace_slashes (filename); 939 940 if (flim) 941 { 942 /* Create any missing directories, replacing NULs by '/'s. 943 Ignore errors. We may have to keep going even after an EEXIST, 944 since the path may contain ".."s; and when there is an EEXIST 945 failure the system may return some other error number. 946 Any problems will eventually be reported when we create the file. */ 947 for (f = filename; f <= flim; f++) 948 if (!*f) 949 { 950 mkdir (filename, 951 S_IRUSR|S_IWUSR|S_IXUSR 952 |S_IRGRP|S_IWGRP|S_IXGRP 953 |S_IROTH|S_IWOTH|S_IXOTH); 954 *f = '/'; 955 } 956 } 957 } 958 959 /* Remove empty ancestor directories of FILENAME. 960 Ignore errors, since the path may contain ".."s, and when there 961 is an EEXIST failure the system may return some other error number. */ 962 void 963 removedirs (filename) 964 char *filename; 965 { 966 size_t i; 967 968 for (i = strlen (filename); i != 0; i--) 969 if (ISSLASH (filename[i]) 970 && ! (ISSLASH (filename[i - 1]) 971 || (filename[i - 1] == '.' 972 && (i == 1 973 || ISSLASH (filename[i - 2]) 974 || (filename[i - 2] == '.' 975 && (i == 2 976 || ISSLASH (filename[i - 3]))))))) 977 { 978 filename[i] = '\0'; 979 if (rmdir (filename) == 0 && verbosity == VERBOSE) 980 say ("Removed empty directory `%s'.\n", filename); 981 filename[i] = '/'; 982 } 983 } 984 985 static time_t initial_time; 986 987 void 988 init_time () 989 { 990 time (&initial_time); 991 } 992 993 /* Make filenames more reasonable. */ 994 995 char * 996 fetchname (at, strip_leading, pstamp) 997 char *at; 998 int strip_leading; 999 time_t *pstamp; 1000 { 1001 char *name; 1002 register char *t; 1003 int sleading = strip_leading; 1004 time_t stamp = (time_t) -1; 1005 1006 while (ISSPACE ((unsigned char) *at)) 1007 at++; 1008 if (debug & 128) 1009 say ("fetchname %s %d\n", at, strip_leading); 1010 1011 name = at; 1012 /* Strip off up to `sleading' leading slashes and null terminate. */ 1013 for (t = at; *t; t++) 1014 { 1015 if (ISSLASH (*t)) 1016 { 1017 while (ISSLASH (t[1])) 1018 t++; 1019 if (--sleading >= 0) 1020 name = t+1; 1021 } 1022 else if (ISSPACE ((unsigned char) *t)) 1023 { 1024 if (set_time | set_utc) 1025 stamp = str2time (t, initial_time, set_utc ? 0L : TM_LOCAL_ZONE); 1026 else 1027 { 1028 /* The head says the file is nonexistent if the timestamp 1029 is the epoch; but the listed time is local time, not UTC, 1030 and POSIX.1 allows local time to be 24 hours away from UTC. 1031 So match any time within 24 hours of the epoch. 1032 Use a default time zone 24 hours behind UTC so that any 1033 non-zoned time within 24 hours of the epoch is valid. */ 1034 stamp = str2time (t, initial_time, -24L * 60 * 60); 1035 if (0 <= stamp && stamp <= 2 * 24L * 60 * 60) 1036 stamp = 0; 1037 } 1038 1039 *t = '\0'; 1040 break; 1041 } 1042 } 1043 1044 if (!*name) 1045 return 0; 1046 1047 /* Allow files to be created by diffing against /dev/null. */ 1048 if (strcmp (at, "/dev/null") == 0) 1049 { 1050 if (pstamp) 1051 *pstamp = 0; 1052 return 0; 1053 } 1054 1055 if (pstamp) 1056 *pstamp = stamp; 1057 1058 return savestr (name); 1059 } 1060 1061 GENERIC_OBJECT * 1062 xmalloc (size) 1063 size_t size; 1064 { 1065 register GENERIC_OBJECT *p = malloc (size); 1066 if (!p) 1067 memory_fatal (); 1068 return p; 1069 } 1070 1071 void 1072 Fseek (stream, offset, ptrname) 1073 FILE *stream; 1074 file_offset offset; 1075 int ptrname; 1076 { 1077 if (file_seek (stream, offset, ptrname) != 0) 1078 pfatal ("fseek"); 1079 } 1080