home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / hold2 / hold.c
Encoding:
C/C++ Source or Header  |  1989-02-03  |  2.9 KB  |  146 lines

  1. /*
  2.  * hold  terminate a pipe, gather stdin into a temporary,
  3.  *     then rename the temporary to the argument's name.
  4.  *
  5.  * Example: ... | hold filename
  6.  *    or: ... | hold > filename
  7.  *
  8.  */
  9.  
  10. #ifdef MSDOS
  11. #include <io.h>
  12. #endif
  13.  
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #ifndef    MSDOS
  17. #include <signal.h>
  18. #endif
  19. FILE *fp = NULL;
  20. int stdoutf;
  21.  
  22. #ifdef MSDOS
  23. char fname[11] = "holdXXXXXX";
  24. #endif
  25. #ifdef M_XENIX
  26. char fname[11] = "holdXXXXXX";
  27. #else
  28. char fname[20] = "/usr/tmp/holdXXXXXX";
  29. #endif
  30.  
  31.  
  32. extern int errno;    /* Declare global error value. */
  33.  
  34. #ifndef MSDOS
  35. /* This routine gains control when a signal is trapped.  It unlinks the
  36.  * temporary file.  This is necessary when a pipe gets broken.
  37.  */
  38. int    Trap()
  39. {
  40. unlink(fname);    /* Ignore errors at this point, we are dead anyway. */
  41. exit(1);
  42. }
  43. #endif
  44.  
  45. int main(argc, argv)
  46.     int argc;
  47.     char *argv[];
  48. {
  49.     int c;
  50.  
  51.     stdoutf = 0;
  52.     if (argc > 1)
  53.         stdoutf = 1;
  54.         
  55.     if (argc > 2) {
  56.     fprintf(stderr, "Usage: ... | hold filename\n");
  57.     fprintf(stderr, " or    ... | hold > filename\n");
  58.     return(1);
  59.     }
  60. #ifndef MSDOS
  61.     /* Trap signals to remove file on. */
  62.     signal(SIGHUP, Trap);
  63.     signal(SIGINT, Trap);
  64.     signal(SIGQUIT, Trap);
  65.     signal(SIGTERM, Trap);
  66. #endif
  67.     if ((fp = fopen(mktemp(fname), "w")) == NULL) 
  68.     errclean(2, "open %s", fname, 0);
  69.     
  70.     while ((c = getchar()) != EOF)
  71.     fputc(c, fp);
  72.  
  73.     if (ferror(stdin) || ferror(fp))
  74.          errclean(3, "copy stdin to %s", 0, fname);
  75.         
  76.     if (fclose(fp) != 0) 
  77.     errclean(4, "close %s", fname, 0);
  78.  
  79.     if (stdoutf) {
  80.         if (rename(fname, argv[1]) != 0)    
  81.             errclean(5, "rename %s to %s", fname, argv[1]);
  82.     }
  83.     else {
  84.     if ((fp = fopen(fname, "r")) == NULL) 
  85.         errclean(6, "open %s", fname, 0);
  86.     
  87.     while ((c = getc(fp)) != EOF)
  88.         fputc(c, stdout);
  89.  
  90.     if (ferror(stdout) || ferror(fp))
  91.             errclean(7, "copy %s to stdout", 0, fname);
  92.         
  93.     if (fclose(fp) != 0) 
  94.         errclean(8, "close %s", fname, 0);
  95.  
  96.     if (unlink(fname) != 0)
  97.         errclean(9, "remove %s", fname, 0);
  98.     }
  99.  
  100.     return(0);
  101. }
  102.  
  103.  
  104. #ifndef MSDOS
  105. int rename(s1, s2)        /* s2 = new name, s1 = existing name */
  106.     char *s1, *s2;
  107. {
  108.     /* assure that new name doesn't exist */
  109.     if (unlink(s2) != 0 && errno != ENOENT) {
  110.     errclean(10, "remove %s", s2, 0);
  111.         return(1);   
  112.         }
  113.     /* connect new name to existing file */
  114.     if (link(s1, s2) != 0) {
  115.     errclean(11, "link %s to %s", s1, s2);
  116.         return(1);   
  117.         }
  118.     /* remove old name for the file */
  119.     if (unlink(s1) != 0) {
  120.     errclean(12, "remove %s", s1, 0);
  121.         return(1);   
  122.         }
  123.     return(0);
  124. }
  125. #endif
  126.  
  127. /*
  128.  * errclean - output error message and exit to system
  129.  */
  130. errclean(code, string, arg1, arg2)
  131.     int code;
  132.     char *string;
  133.     char *arg1, *arg2;
  134. {
  135.     char lstr[80];
  136.  
  137.     if (fp != NULL) {
  138.     (void)unlink(fname);
  139.         fp = NULL;
  140.     }
  141.     sprintf(lstr, "hold %2d: can't %s\n", code, string);
  142.     fprintf(stderr, lstr, arg1, arg2);
  143.     exit(code);
  144. }
  145.  
  146.