home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / rn_4_3_blars.lzh / util.c < prev    next >
Text File  |  1990-08-26  |  11KB  |  548 lines

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