home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume17 / e2 / part03 / do_vi.c next >
C/C++ Source or Header  |  1989-02-08  |  5KB  |  262 lines

  1. #include "e.h"
  2.  
  3. /* 
  4.  * do_vi()
  5.  *
  6.  * Split the arguments (if any) in 'thing' up to be passed to execvp,
  7.  * and exec vi on them. The arguments in 'thing' are space separated.
  8.  * Just walk down the 'thing' array, zero the spaces and set pointers 
  9.  * to the arguments.
  10.  *
  11.  */
  12.  
  13. void
  14. do_vi(thing)
  15. char *thing;
  16. {
  17.     char *args[MAX_ARGS];
  18.     register int i = 1;
  19.     int go_home = 0;
  20.  
  21.     args[0] = "vi";
  22.     skip_white(thing);
  23.  
  24.     while (*thing){
  25.         register char *tmp = thing;
  26.         skip_to_white(tmp);
  27.         if (*tmp) *tmp++ = '\0';
  28.         skip_white(tmp);
  29.  
  30.         if (i > 1 || (*thing != '-' && *thing != '+')){
  31.             if (safety_first(thing)){
  32.                 /*
  33.                  * Have to go home for this one.
  34.                  * Grab some space to put the new filename into.
  35.                  * The filename is to be cwd/thing.
  36.                  *
  37.                  */
  38.                 char *space = sbrk(MAXPATHLEN + 1);
  39.                 go_home = 1;
  40.                 if (space == (char *)-1){
  41.                     e_error("Could not sbrk.");
  42.                 }
  43.                 sprintf(space, "%s/%s", cwd, thing);
  44.                 thing = space;
  45.             }
  46.         }
  47.         args[i++] = thing;
  48.         thing = tmp;
  49.     }
  50.  
  51.     args[i] = NULL;
  52.  
  53.     if (go_home && chdir(home) == -1){
  54.         e_error("Could not chdir to '%s'.", home);
  55.     }
  56.         
  57.     if (execvp(VI, args) == -1){
  58.         e_error("Could not execvp '%s'", VI);
  59.     }
  60. }
  61.  
  62.  
  63. int
  64. safety_first(s)
  65. char *s;
  66. {
  67.     register char *slash;
  68.     struct stat sbuf;
  69.     char away_dir[MAXPATHLEN];
  70.     int away;
  71.     int own;
  72.  
  73.     /*
  74.      * If they are not concerned with inheritance, just return.
  75.      *
  76.      */
  77.     if (!safe_inherit && !inherit){
  78.         return 0;
  79.     }
  80.  
  81.     /*
  82.      * See if there is a .exrc file in the directory in which the file we
  83.      * are going to be editing lives.
  84.      */
  85.     slash = rindex(s, '/');
  86.  
  87.     if (slash){
  88.         /*
  89.          * The file we are editing lies (probably) in a directory that is 
  90.          * not the one we are in. Check it by inode numbers though.
  91.          *
  92.          */
  93.         char tmp[MAXPATHLEN];
  94.         ino_t here_ino;
  95.  
  96.         *slash = '\0';
  97.         ok_sprintf(away_dir, "%s", s);
  98.         *slash = '/';
  99.         ok_sprintf(tmp, "%s/.exrc", away_dir);
  100.  
  101.         if (stat(tmp, &sbuf) == -1){
  102.             /*
  103.              * There is no .exrc file.
  104.              *
  105.              */
  106.             return 0;
  107.         }
  108.         
  109.         /*
  110.          * There is a .exrc file.
  111.          *
  112.          */
  113.         if (uid == sbuf.st_uid){
  114.             /*
  115.              * And we own it.
  116.              *
  117.              */
  118.             away = 1;
  119.             own = 1;
  120.         }
  121.         else{
  122.             /*
  123.              * We don't own the .exrc file. 
  124.              *
  125.              */
  126.             own = 0;
  127.         }
  128.  
  129.         /*
  130.          * Decide whether or not the file we are going to edit is in
  131.          * this directory. We may have been deceived by the presence of the
  132.          * '/' since the filename could be ../this_dir etc etc.
  133.          *
  134.          */
  135.  
  136.         if (stat(cwd, &sbuf) == -1){
  137.             e_error("Cannot stat '%s'.", cwd);
  138.         }
  139.         here_ino = sbuf.st_ino;
  140.  
  141.         if (stat(away_dir, &sbuf) == -1){
  142.             e_error("Cannot stat '%s'.", away_dir);
  143.         }
  144.  
  145.         if (sbuf.st_ino == here_ino){
  146.              away = 0;
  147.         }
  148.         else{
  149.             away = 1;
  150.         }
  151.     }
  152.     else{
  153.         /*
  154.          * The file is in this directory.
  155.          *
  156.          */
  157.  
  158.         /*
  159.          * We know we are away, there was no '/' in the filename.
  160.          * The possibility of the filename being a link is excluded I
  161.          * think, because earlier on we checked for regular files.
  162.          * I'll check this again. In any case no harm could come as
  163.          * at worst we would attempt to vi a directory.
  164.          *
  165.          */
  166.         away = 0;
  167.  
  168.         if (stat(".exrc", &sbuf) == -1){
  169.             /*
  170.              * No .exrc file.
  171.              *
  172.              */
  173.             return 0;
  174.         }
  175.  
  176.         if (uid == sbuf.st_uid){
  177.             own = 1;
  178.         }
  179.         else{
  180.             own = 0;
  181.         }
  182.     }
  183.  
  184.     /*
  185.      * We have now set up 'away' and 'own'.
  186.      *
  187.      * away = 1  =>  The file we are editing is not in our current directory.
  188.      * away = 0  =>  The file we are editing is in our current directory.
  189.      *
  190.      * own = 1   =>  We own the .exrc file.
  191.      * own = 0   =>  We do not own the .exrc file.
  192.      *
  193.      *
  194.      */
  195.  
  196.     /*
  197.      * It's in this directory and we own it. So just return and pretend
  198.      * to be a normal vi :-)
  199.      *
  200.      */
  201.     if (!away && own){
  202.         return 0;
  203.     }
  204.  
  205.     /*
  206.      * It's in this directory and we don't own it and we don't want to inherit
  207.      * it. 
  208.      *
  209.      * Return 1 to indicate that the filename that needs to be edited 
  210.      * should now be preceeded by 'cwd/'. And that we need to chdir to home
  211.      * before we exec vi.
  212.      *
  213.      */
  214.     if (!away && !own && safe_inherit){
  215.         return 1;
  216.     }
  217.  
  218.     /*
  219.      * The other option is that it's in this directory and we don't own
  220.      * it and either 1) inherit is set or 2) inherit is not set AND neither
  221.      * is safe_inherit. In either case we are going to inherit the thing.
  222.      *
  223.      */
  224.  
  225.      /*
  226.       * Now to the cases where the file we are going to edit is not in
  227.       * this directory.
  228.       *
  229.       */
  230.  
  231.     /*
  232.      * It's not in this directory and we own it and we want to inherit. 
  233.      * So chdir over there before returning.
  234.      *
  235.      */
  236.     if (away && own && inherit){
  237.         if (chdir(away_dir) == -1){
  238.             e_error("Could not chdir to '%s'.", away_dir);
  239.         }
  240.         return 0;
  241.     }
  242.  
  243.     /*
  244.      * It's not in this directory and we don't own it and we want to inherit
  245.      * even if it's not safe. So chdir over there before returning.
  246.      *
  247.      */
  248.     if (away && !own && inherit && !safe_inherit){
  249.         if (chdir(away_dir) == -1){
  250.             e_error("Could not chdir to '%s'.", away_dir);
  251.         }
  252.         return 0;
  253.     }
  254.  
  255.     /*
  256.      * And I think that's about it. Time will tell.
  257.      *
  258.      */
  259.     
  260.     return 0;
  261. }
  262.