home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / trn / part11 / util.c < prev   
C/C++ Source or Header  |  1991-08-22  |  11KB  |  505 lines

  1. /* $Header: util.c,v 4.3.3.3 91/01/16 03:41:50 davison Trn $
  2.  *
  3.  * $Log:    util.c,v $
  4.  * Revision 4.3.3.3  91/01/16  03:41:50  davison
  5.  * Integrated rn patches 48-54.
  6.  * 
  7.  * Revision 4.3.3.2  90/08/20  16:51:44  davison
  8.  * Fixed getcwd call to not overflow any buffers.
  9.  * 
  10.  * Revision 4.3.3.1  90/07/21  20:34:10  davison
  11.  * Initial Trn Release
  12.  * 
  13.  * Revision 4.3.2.8  90/11/22  13:54:06  sob
  14.  * Made changes to keep more preprocessors happy.
  15.  * 
  16.  * Revision 4.3.2.7  90/10/01  01:52:18  sob
  17.  * Altered the preprocessor defines on GETWD/GETCWD per suggestion by
  18.  * rsm@math.arizona.edu.
  19.  * 
  20.  * Revision 4.3.2.6  90/04/23  00:24:42  sob
  21.  * A bit of clean up.
  22.  * 
  23.  * Revision 4.3.2.5  90/03/17  21:34:21  sob
  24.  * Reworked VOIDSIG into SIGRET.
  25.  * 
  26.  * Revision 4.3.2.4  89/12/14  23:58:54  sob
  27.  * Fixed small bug reported by fletcher@cs.utexas.edu in getwd().
  28.  * 
  29.  * Revision 4.3.2.3  89/11/08  04:47:11  sob
  30.  * Added VOIDSIG handling for SunOS 4.X
  31.  * 
  32.  * Revision 4.3.2.2  89/11/07  23:19:35  sob
  33.  * Bug fixes for SIGSTP problems
  34.  * 
  35.  * Revision 4.3.2.1  89/11/06  01:03:21  sob
  36.  * Added RRN support from NNTP 1.5
  37.  * 
  38.  * Revision 4.3.1.2  85/05/15  14:44:27  lwall
  39.  * Last arg of execl changed from 0 to Nullch [(char*)0].
  40.  * 
  41.  * Revision 4.3.1.1  85/05/10  11:41:30  lwall
  42.  * Branch for patches.
  43.  * 
  44.  * Revision 4.3  85/05/01  11:51:44  lwall
  45.  * Baseline for release with 4.3bsd.
  46.  * 
  47.  */
  48.  
  49. #include "EXTERN.h"
  50. #include "common.h"
  51. #include "final.h"
  52. #include "ndir.h"
  53. #include "INTERN.h"
  54. #include "util.h"
  55.  
  56. void
  57. util_init()
  58. {
  59.     ;
  60. }
  61.     
  62. /* fork and exec a shell command */
  63.  
  64. int
  65. doshell(shl,s)
  66. char *s, *shl;
  67. {
  68.     int status, pid, w;
  69.     char *shell;
  70.  
  71. #ifdef SIGTSTP
  72.     sigset(SIGTSTP,SIG_DFL);
  73.     sigset(SIGTTOU,SIG_DFL);
  74.     sigset(SIGTTIN,SIG_DFL);
  75. #endif
  76.     if (shl != Nullch)
  77.     shell = shl;
  78.     else if ((shell = getenv("SHELL")) == Nullch || !*shell)
  79.     shell = PREFSHELL;
  80.     if ((pid = vfork()) == 0) {
  81. #ifdef SERVER
  82.         int i;
  83.  
  84.     /* This is necessary to keep bourne shell from puking */
  85.  
  86.         for (i = 3; i < 10; ++i)
  87.                 close(i);
  88. #endif /* SERVER */
  89.  
  90.     if (*s)
  91.         execl(shell, shell, "-c", s, Nullch);
  92.     else
  93.         execl(shell, shell, Nullch, Nullch, Nullch);
  94.     _exit(127);
  95.     }
  96.     signal(SIGINT, SIG_IGN);
  97. #ifdef SIGQUIT
  98.     signal(SIGQUIT, SIG_IGN);
  99. #endif
  100.     waiting = TRUE;
  101.     while ((w = wait(&status)) != pid && w != -1)
  102.     ;
  103.     if (w == -1)
  104.     status = -1;
  105.     waiting = FALSE;
  106.     sigset(SIGINT, int_catcher);    /* always catch interrupts */
  107. #ifdef SIGQUIT
  108.     signal(SIGQUIT, SIG_DFL);
  109. #endif
  110. #ifdef SIGTSTP
  111.     sigset(SIGTSTP,stop_catcher);
  112.     sigset(SIGTTOU,stop_catcher);
  113.     sigset(SIGTTIN,stop_catcher);
  114. #endif
  115.     return status;
  116. }
  117.  
  118. static char nomem[] = "rn: out of memory!\n";
  119.  
  120. /* paranoid version of malloc */
  121.  
  122. char *
  123. safemalloc(size)
  124. MEM_SIZE size;
  125. {
  126.     char *ptr;
  127.     char *malloc();
  128.  
  129.     ptr = malloc(size ? size : (MEM_SIZE)1);
  130.     if (ptr != Nullch)
  131.     return ptr;
  132.     else {
  133.     fputs(nomem,stdout) FLUSH;
  134.     sig_catcher(0);
  135.     }
  136.     /*NOTREACHED*/
  137. }
  138.  
  139. /* paranoid version of realloc */
  140.  
  141. char *
  142. saferealloc(where,size)
  143. char *where;
  144. MEM_SIZE size;
  145. {
  146.     char *ptr;
  147.     char *realloc();
  148.  
  149.     ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  150.     if (ptr != Nullch)
  151.     return ptr;
  152.     else {
  153.     fputs(nomem,stdout) FLUSH;
  154.     sig_catcher(0);
  155.     }
  156.     /*NOTREACHED*/
  157. }
  158.  
  159. /* safe version of string copy */
  160.  
  161. char *
  162. safecpy(to,from,len)
  163. char *to;
  164. register char *from;
  165. register int len;
  166. {
  167.     register char *dest = to;
  168.  
  169.     if (from != Nullch) 
  170.     for (len--; len && (*dest++ = *from++); len--) ;
  171.     *dest = '\0';
  172.     return to;
  173. }
  174.  
  175. /* safe version of string concatenate, with \n deletion and space padding */
  176.  
  177. char *
  178. safecat(to,from,len)
  179. char *to;
  180. register char *from;
  181. register int len;
  182. {
  183.     register char *dest = to;
  184.  
  185.     len--;                /* leave room for null */
  186.     if (*dest) {
  187.     while (len && *dest++) len--;
  188.     if (len) {
  189.         len--;
  190.         *(dest-1) = ' ';
  191.     }
  192.     }
  193.     if (from != Nullch)
  194.     while (len && (*dest++ = *from++)) len--;
  195.     if (len)
  196.     dest--;
  197.     if (*(dest-1) == '\n')
  198.     dest--;
  199.     *dest = '\0';
  200.     return to;
  201. }
  202.  
  203. /* copy a string up to some (non-backslashed) delimiter, if any */
  204.  
  205. char *
  206. cpytill(to,from,delim)
  207. register char *to, *from;
  208. register int delim;
  209. {
  210.     for (; *from; from++,to++) {
  211.     if (*from == '\\' && from[1] == delim)
  212.         from++;
  213.     else if (*from == delim)
  214.         break;
  215.     *to = *from;
  216.     }
  217.     *to = '\0';
  218.     return from;
  219. }
  220.  
  221. /* return ptr to little string in big string, NULL if not found */
  222.  
  223. char *
  224. instr(big, little)
  225. char *big, *little;
  226.  
  227. {
  228.     register char *t, *s, *x;
  229.  
  230.     for (t = big; *t; t++) {
  231.     for (x=t,s=little; *s; x++,s++) {
  232.         if (!*x)
  233.         return Nullch;
  234.         if (*s != *x)
  235.         break;
  236.     }
  237.     if (!*s)
  238.         return t;
  239.     }
  240.     return Nullch;
  241. }
  242.  
  243. /* effective access */
  244.  
  245. #ifdef SETUIDGID
  246. int
  247. eaccess(filename, mod)
  248. char *filename;
  249. int mod;
  250. {
  251.     int protection, euid;
  252.     
  253.     mod &= 7;                /* remove extraneous garbage */
  254.     if (stat(filename, &filestat) < 0)
  255.     return -1;
  256.     euid = geteuid();
  257.     if (euid == ROOTID)
  258.     return 0;
  259.     protection = 7 & (filestat.st_mode >>
  260.       (filestat.st_uid == euid ? 6 :
  261.         (filestat.st_gid == getegid() ? 3 : 0)
  262.       ));
  263.     if ((mod & protection) == mod)
  264.     return 0;
  265.     errno = EACCES;
  266.     return -1;
  267. }
  268. #endif
  269.  
  270. /*
  271.  * Get working directory
  272.  */
  273. #ifndef GETWD
  274. #ifdef GETCWD
  275. char *
  276. getwd(np)
  277. char *np;
  278. {
  279.     char * name;
  280.     extern char * getcwd();
  281.     name = getcwd(np,512);
  282.     return(name);
  283. }
  284. #else
  285. char *
  286. getwd(np)            /* shorter but slower */
  287. char *np;
  288. {
  289.     FILE *popen();
  290.     FILE *pipefp = popen("/bin/pwd","r");
  291.  
  292.     if (pipefp == Nullfp) {
  293.     printf("Can't run /bin/pwd\n") FLUSH;
  294.     finalize(1);
  295.     }
  296.     fgets(np,512,pipefp);
  297.     np[strlen(np)-1] = '\0';    /* wipe out newline */
  298.     pclose(pipefp);
  299.     return np;
  300. }
  301. #endif
  302. #endif
  303. /* just like fgets but will make bigger buffer as necessary */
  304.  
  305. char *
  306. get_a_line(original_buffer,buffer_length,fp)
  307. char *original_buffer;
  308. register int buffer_length;
  309. FILE *fp;
  310. {
  311.     register int bufix = 0;
  312.     register int nextch;
  313.     register char *some_buffer_or_other = original_buffer;
  314.  
  315.     do {
  316.     if (bufix >= buffer_length) {
  317.         buffer_length *= 2;
  318.         if (some_buffer_or_other == original_buffer) {
  319.                     /* currently static? */
  320.         some_buffer_or_other = safemalloc((MEM_SIZE)buffer_length+1);
  321.         strncpy(some_buffer_or_other,original_buffer,buffer_length/2);
  322.                     /* so we must copy it */
  323.         }
  324.         else {            /* just grow in place, if possible */
  325.         some_buffer_or_other = saferealloc(some_buffer_or_other,
  326.             (MEM_SIZE)buffer_length+1);
  327.         }
  328.     }
  329.     if ((nextch = getc(fp)) == EOF)
  330.         return Nullch;
  331.     some_buffer_or_other[bufix++] = (char) nextch;
  332.     } while (nextch && nextch != '\n');
  333.     some_buffer_or_other[bufix] = '\0';
  334.     len_last_line_got = bufix;
  335.     return some_buffer_or_other;
  336. }
  337.  
  338. /* copy a string to a safe spot */
  339.  
  340. char *
  341. savestr(str)
  342. char *str;
  343. {
  344.     register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
  345.  
  346.     strcpy(newaddr,str);
  347.     return newaddr;
  348. }
  349.  
  350. int
  351. makedir(dirname,nametype)
  352. register char *dirname;
  353. int nametype;
  354. {
  355. #ifdef MAKEDIR
  356.     register char *end;
  357.     register char *s;
  358.     char tmpbuf[1024];
  359.     register char *tbptr = tmpbuf+5;
  360.  
  361.     for (end = dirname; *end; end++) ;    /* find the end */
  362.     if (nametype == MD_FILE) {        /* not to create last component? */
  363.     for (--end; end != dirname && *end != '/'; --end) ;
  364.     if (*end != '/')
  365.         return 0;            /* nothing to make */
  366.     *end = '\0';            /* isolate file name */
  367.     }
  368.     strcpy(tmpbuf,"mkdir");
  369.  
  370.     s = end;
  371.     for (;;) {
  372.     if (stat(dirname,&filestat) >= 0 && (filestat.st_mode & S_IFDIR)) {
  373.                     /* does this much exist as a dir? */
  374.         *s = '/';            /* mark this as existing */
  375.         break;
  376.     }
  377.     s = rindex(dirname,'/');    /* shorten name */
  378.     if (!s)                /* relative path! */
  379.         break;            /* hope they know what they are doing */
  380.     *s = '\0';            /* mark as not existing */
  381.     }
  382.     
  383.     for (s=dirname; s <= end; s++) {    /* this is grody but efficient */
  384.     if (!*s) {            /* something to make? */
  385.         sprintf(tbptr," %s",dirname);
  386.         tbptr += strlen(tbptr);    /* make it, sort of */
  387.         *s = '/';            /* mark it made */
  388.     }
  389.     }
  390.     if (nametype == MD_DIR)        /* don't need final slash unless */
  391.     *end = '\0';            /*  a filename follows the dir name */
  392.  
  393.     return (tbptr==tmpbuf+5 ? 0 : doshell(sh,tmpbuf));
  394.                     /* exercise our faith */
  395. #else
  396.     sprintf(cmd_buf,"%s %s %d", filexp(DIRMAKER), dirname, nametype);
  397.     return doshell(sh,cmd_buf);
  398. #endif
  399. }
  400.  
  401. #ifdef SETENV
  402. static bool firstsetenv = TRUE;
  403. extern char **environ;
  404.  
  405. void
  406. setenv(nam,val)
  407. char *nam, *val;
  408. {
  409.     register int i=envix(nam);        /* where does it go? */
  410.  
  411.     if (!environ[i]) {            /* does not exist yet */
  412.     if (firstsetenv) {        /* need we copy environment? */
  413.         int j;
  414. #ifndef lint
  415.         char **tmpenv = (char**)    /* point our wand at memory */
  416.         safemalloc((MEM_SIZE) (i+2) * sizeof(char*));
  417. #else
  418.         char **tmpenv = Null(char **);
  419. #endif /* lint */
  420.     
  421.         firstsetenv = FALSE;
  422.         for (j=0; j<i; j++)        /* copy environment */
  423.         tmpenv[j] = environ[j];
  424.         environ = tmpenv;        /* tell exec where it is now */
  425.     }
  426. #ifndef lint
  427.     else
  428.         environ = (char**) saferealloc((char*) environ,
  429.         (MEM_SIZE) (i+2) * sizeof(char*));
  430.                     /* just expand it a bit */
  431. #endif /* lint */
  432.     environ[i+1] = Nullch;    /* make sure it's null terminated */
  433.     }
  434.     environ[i] = safemalloc((MEM_SIZE) strlen(nam) + strlen(val) + 2);
  435.                     /* this may or may not be in */
  436.                     /* the old environ structure */
  437.     sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
  438. }
  439.  
  440. int
  441. envix(nam)
  442. char *nam;
  443. {
  444.     register int i, len = strlen(nam);
  445.  
  446.     for (i = 0; environ[i]; i++) {
  447.     if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
  448.         break;            /* strnEQ must come first to avoid */
  449.     }                    /* potential SEGV's */
  450.     return i;
  451. }
  452. #endif
  453.  
  454. void
  455. notincl(feature)
  456. char *feature;
  457. {
  458.     printf("\nNo room for feature \"%s\" on this machine.\n",feature) FLUSH;
  459. }
  460.  
  461. char *
  462. getval(nam,def)
  463. char *nam,*def;
  464. {
  465.     char *val;
  466.  
  467.     if ((val = getenv(nam)) == Nullch || !*val)
  468.     val = def;
  469.     return val;
  470. }
  471.  
  472. /* grow a static string to at least a certain length */
  473.  
  474. void
  475. growstr(strptr,curlen,newlen)
  476. char **strptr;
  477. int *curlen;
  478. int newlen;
  479. {
  480.     if (newlen > *curlen) {        /* need more room? */
  481.     if (*curlen)
  482.         *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
  483.     else
  484.         *strptr = safemalloc((MEM_SIZE)newlen);
  485.     *curlen = newlen;
  486.     }
  487. }
  488.  
  489. void
  490. setdef(buffer,dflt)
  491. char *buffer,*dflt;
  492. {
  493. #ifdef STRICTCR
  494.     if (*buffer == ' ')
  495. #else
  496.     if (*buffer == ' ' || *buffer == '\n')
  497. #endif
  498.     {
  499.     if (*dflt == '^' && isupper(dflt[1]))
  500.         *buffer = Ctl(dflt[1]);
  501.     else
  502.         *buffer = *dflt;
  503.     }
  504. }
  505.