home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8709 / 3 / install.c next >
Encoding:
C/C++ Source or Header  |  1987-09-08  |  4.1 KB  |  217 lines

  1. /*  $Revision:$
  2. **  Install
  3. */
  4.  
  5. /*
  6. **  Configuration section.  This is all done in the Makefile.
  7. */
  8. /* #define SYS_WAIT            /* Have <sys/wait.h>?        */
  9. /* #define FORK        vfork        /* If you have this use it...    */
  10. /* #define FORK        fork        /* ...else use this        */
  11. /* #define EXIT                /* Needed to avoid stdio?    */
  12. /* #define CHOWN_F_FLAG            /* Have "chown -f"?        */
  13. /* #define CHGRP_F_FLAG            /* Have "chgrp -f"?        */
  14. /* #define STDERR    2        /* Guess what this is        */
  15. /* #define DEF_OWNER    "root"        /* Defalt owner of new files    */
  16. /* #define DEF_GROUP    "system"    /* Default group for new files    */
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #ifdef    SYS_WAIT
  23. #include <sys/wait.h>
  24. #define WAITER        union wait
  25. #else
  26. #define WAITER        int
  27. #endif    /* SYS_WAIT */
  28.  
  29.  
  30. char     Source[BUFSIZ];
  31. char     Destination[BUFSIZ];
  32. char    *Pname;
  33.  
  34. char    *RMvec[] = {
  35.     "/bin/rm", "-f", Destination, NULL
  36. };
  37.  
  38. char    *STRIPvec[] = {
  39.     "/bin/strip", Destination, NULL
  40. };
  41.  
  42. char    *MOVEvec[] = {
  43.     "/bin/mv", Source, Destination, NULL
  44. #define MV_CP        MOVEvec[0]
  45. };
  46.  
  47.  
  48. char    *CHMODvec[] = {
  49.     "/bin/chmod", "755", Destination, NULL
  50. #define MODE        CHMODvec[1]
  51. };
  52.  
  53. char    *CHOWNvec[] = {
  54. #ifdef    CHOWN_F_FLAG
  55.     "/etc/chown", "-f", DEF_OWNER, Destination, NULL
  56. #define OWNER        CHOWNvec[2]
  57. #else
  58.     "/etc/chown", DEF_OWNER, Destination, NULL
  59. #define OWNER        CHOWNvec[1]
  60. #endif    /* CHOWN_F_FLAG */
  61. };
  62.  
  63. char    *CHGRPvec[] = {
  64. #ifdef    CHGRP_F_FLAG
  65.     "/bin/chgrp", "-f", "system", Destination, NULL
  66. #define GROUP        CHGRPvec[3]
  67. #else
  68.     "/bin/chgrp", "system", Destination, NULL
  69. #define GROUP        CHGRPvec[2]
  70. #endif    /* CHGRP_F_FLAG */
  71. };
  72.  
  73. /*
  74. **  Externals.
  75. */
  76. extern char    **environ;
  77. extern char     *optarg;
  78. extern int      optind;
  79. extern char     *IDX();
  80. extern char     *strcpy();
  81. extern char     *strcat();
  82.  
  83. #ifdef    lint
  84. char    **environ;
  85. char     *optarg;
  86. int      optind;
  87. #endif    /* lint */
  88.  
  89.  
  90.  
  91. #ifndef    lint
  92. #ifdef    EXIT
  93. /*
  94. **  Avoid standard I/O crufties.  Not needed on systems with a proper
  95. **  C library.
  96. */
  97. exit(X)
  98.     int         X;
  99. {
  100.     _exit(X);
  101. }
  102. #endif    /* EXIT */
  103. #endif    /* lint */
  104.  
  105.  
  106. /*
  107. **  Print error message and die.  No standard I/O.
  108. */
  109. void
  110. Err(s)
  111.     char    *s;
  112. {
  113.     (void)write(STDERR, Pname, strlen(Pname));
  114.     (void)write(STDERR, ":  ", 3);
  115.     (void)write(STDERR, s, strlen(s));
  116.     (void)write(STDERR, ".\n", 2);
  117.     exit(1);
  118. }
  119.  
  120.  
  121. /*
  122. **  Spin off an argv[] command, and wait for it.
  123. */
  124. void
  125. Doit(av)
  126.     char    *av[];
  127. {
  128.     WAITER     W;
  129.     int         i;
  130.     int         j;
  131.  
  132. for (i = 0; av[i]; i++) printf("%d.  %s\n", i, av[i]);
  133.     /* Spin until we can fork. */
  134.     while ((i = FORK()) < 0) {
  135.     perror("fork");
  136.     (void)sleep(1);
  137.     }
  138.  
  139.     /* Kid becomes the program. */
  140.     if (i == 0) {
  141.     execve(av[0], av, environ);
  142.     perror(av[0]);
  143.     _exit(1);
  144.     }
  145.  
  146.     /* Parent waits for kid, and probably loops on error. */
  147.     while ((j = wait(&W)) != i)
  148.     if (j < 0)
  149.         perror("wait");
  150. }
  151.  
  152.  
  153. main(ac, av)
  154.     register int     ac;
  155.     register char    *av[];
  156. {
  157.     register int     c;
  158.     int             Strip;
  159.     struct stat         Sb;
  160.  
  161.     Pname = (Pname = IDX(av[0], '/')) ? Pname + 1 : av[0];
  162.     for (Strip = 0; (c = getopt(ac, av, "scm:o:g:")) != EOF; )
  163.     switch (c) {
  164.         case 's':
  165.         Strip++;
  166.         break;
  167.         case 'c':
  168.         MV_CP = "/bin/cp";
  169.         break;
  170.         case 'm':
  171.         MODE = optarg;
  172.         break;
  173.         case 'o':
  174.         OWNER = optarg;
  175.         break;
  176.         case 'g':
  177.         GROUP = optarg;
  178.         break;
  179.     }
  180.  
  181.     /* Check number of files specified. */
  182.     switch (ac -= optind) {
  183.     case 1:
  184.         Err("No destination specified");
  185.     case 3:
  186.         Err("Too many files specified");
  187.     }
  188.     av += optind;
  189.  
  190.     /* Is the source an existing, standard file? */
  191.     if (stat(av[0], &Sb) < 0)
  192.     Err("Source file doesn't exist");
  193.     if ((Sb.st_mode & S_IFMT) != S_IFREG)
  194.     Err("Source isn't a regular file");
  195.  
  196.     /* Is the destination the same as the source? */
  197.     if (strcmp(av[0], av[1]) == 0 || strcmp(av[1], ".") == 0)
  198.     Err("Can't move file onto itself");
  199.     (void)strcpy(Source, av[0]);
  200.  
  201.     /* If the destination is a directory, make a file. */
  202.     if (stat(av[1], &Sb) >= 0 && (Sb.st_mode & S_IFMT) == S_IFDIR)
  203.     (void)strcat(strcat(strcpy(Destination, av[0]), "/"), av[1]);
  204.     else
  205.     (void)strcpy(Destination, av[1]);
  206.  
  207.     Doit(RMvec);
  208.     Doit(MOVEvec);
  209.     if (Strip)
  210.     Doit(STRIPvec);
  211.     Doit(CHOWNvec);
  212.     Doit(CHGRPvec);
  213.     Doit(CHMODvec);
  214.  
  215.     exit(0);
  216. }
  217.