home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trn / part02 / mt-misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  4.7 KB  |  229 lines

  1. /* $Id: mt-misc.c,v 4.4.3.1 1991/11/22 04:12:15 davison Trn $
  2. **
  3. ** $Log: mt-misc.c,v $
  4. ** Revision 4.4.3.1  1991/11/22  04:12:15  davison
  5. ** Trn Release 2.0
  6. ** 
  7. */
  8.  
  9. #include "EXTERN.h"
  10. #include "common.h"
  11. #include "threads.h"
  12. #include "mthreads.h"
  13.  
  14. char *lib, *rnlib, *mtlib, *spool, *threaddir, *homedir;
  15. int locked = 0, cron_locking = 0;
  16.  
  17. void
  18. mt_init()
  19. {
  20.     /* Set up a nice friendly umask. */
  21.     umask(002);
  22.  
  23.     /* Init the directory strings, possibly translating them into real paths */
  24.     homedir = getenv("HOME");
  25.     if (homedir == Nullch) {
  26.     homedir = getenv("LOGDIR");
  27.     }
  28.     spool = savestr(file_exp(SPOOL));
  29.     lib = savestr(file_exp(LIB));
  30.     rnlib = savestr(file_exp(RNLIB));
  31.     mtlib = savestr(file_exp(MTLIB));
  32.     threaddir = savestr(file_exp(THREAD_DIR));
  33. }
  34.  
  35. /* Make sure we're not already running by creating a lock file. */
  36. long
  37. mt_lock(which_lock, sig)
  38. int which_lock;
  39. int sig;
  40. {
  41.     char buff[LBUFLEN], *filename;
  42.     FILE *fp;
  43.  
  44.     sprintf(buff, "%s.%ld", file_exp(MTPRELOCK), (long)getpid());
  45.     if ((fp = fopen(buff, "w")) == Nullfp) {
  46.     log_entry("Unable to create lock temporary `%s'.\n", buff);
  47.     wrap_it_up(1);
  48.     }
  49.     fprintf(fp, "%s%ld\n", which_lock == DAEMON_LOCK ? "pid " : nullstr,
  50.     (long)getpid());
  51.     fclose(fp);
  52.  
  53.     /* Try to link to lock file. */
  54.     if (which_lock == DAEMON_LOCK) {
  55.     filename = file_exp(MTDLOCK);
  56.     } else {
  57.     filename = file_exp(MTLOCK);
  58.     }
  59.   dolink:
  60.     while (link(buff, filename) < 0) {
  61.       long otherpid;
  62.     if ((fp = fopen(filename, "r")) == Nullfp) {
  63.         log_entry("unable to open %s\n", filename);
  64.         if (cron_locking) {
  65.         goto Sleep;
  66.         }
  67.         unlink(buff);
  68.         wrap_it_up(1);
  69.     }
  70.     if (fscanf(fp, "%ld", &otherpid) != 1) { 
  71.         log_entry("unable to read pid from %s\n", filename);
  72.         fclose(fp);
  73.         if (cron_locking) {
  74.         goto Sleep;
  75.         }
  76.         unlink(buff);
  77.         wrap_it_up(1);
  78.     }
  79.     fclose(fp);
  80.     if (kill(otherpid, sig) == -1 && errno == ESRCH) {
  81.         if (unlink(filename) == -1) {
  82.         log_entry("unable to unlink lockfile %s\n", filename);
  83.         unlink(buff);
  84.         wrap_it_up(1);
  85.         }
  86.         goto dolink;
  87.     }
  88.     if (cron_locking) {
  89.       Sleep:
  90.         sleep(60);
  91.         continue;
  92.     }
  93.     unlink(buff);
  94.     return otherpid;
  95.     }
  96.     unlink(buff);            /* remove temporary LOCK.<pid> file */
  97.     locked |= which_lock;
  98.     return 0;                /* return success */
  99. }
  100.  
  101. void
  102. mt_unlock(which_lock)
  103. int which_lock;
  104. {
  105.     which_lock &= locked;
  106.     if (which_lock & PASS_LOCK) {
  107.     unlink(file_exp(MTLOCK));        /* remove single-pass lock */
  108.     }
  109.     if (which_lock & DAEMON_LOCK) {
  110.     unlink(file_exp(MTDLOCK));        /* remove daemon lock */
  111.     }
  112.     locked &= ~which_lock;
  113. }
  114.  
  115. /* Interpret rn's %x prefixes and ~name expansions without including tons
  116. ** of useless source.  NOTE:  names that don't start with '/', '%' or '~'
  117. ** are prefixed with the SPOOL directory.  (Note that ~'s don't work yet.)
  118. */
  119. char *
  120. file_exp(name)
  121. char *name;
  122. {
  123.     static char namebuf[MAXFILENAME];
  124.  
  125.     if (*name == '/') {    /* fully qualified names are left alone */
  126.     return name;
  127.     }
  128.     switch (name[0]) {
  129.     case '%':            /* interpret certain %x values */
  130.     switch (name[1]) {
  131.     case 'P':
  132.         strcpy(namebuf, spool);
  133.         break;
  134.     case 'w':
  135.         strcpy(namebuf, mtlib);
  136.         break;
  137.     case 'W':
  138.         strcpy(namebuf, threaddir);
  139.         break;
  140.     case 'x':
  141.         strcpy(namebuf, lib);
  142.         break;
  143.     case 'X':
  144.         strcpy(namebuf, rnlib);
  145.         break;
  146.     default:
  147.         log_entry("Unknown expansion: %s\n", name);
  148.         wrap_it_up(1);
  149.     }
  150.     strcat(namebuf, name+2);
  151.     break;
  152.     case '~':
  153.     {
  154.     char *s = name + 1;
  155.  
  156.     if (!*s || *s == '/') {
  157.         sprintf(namebuf, "%s%s", homedir, s);
  158.     } else {
  159.         log_entry("~name expansions not implemented.");
  160.         wrap_it_up(1);
  161.     }
  162.     }
  163.     default:            /* all "normal" names are relative to SPOOL */
  164.     sprintf(namebuf, "%s/%s", spool, name);
  165.     break;
  166.     }
  167.     return namebuf;
  168. }
  169.  
  170. #ifndef lint
  171. /* A malloc that bombs-out when memory is exhausted. */
  172. char *
  173. safemalloc(amount)
  174. MEM_SIZE amount;
  175. {
  176.     register char *cp;
  177.     char *malloc();
  178.  
  179.     if ((cp = malloc(amount)) == Nullch) {
  180.     log_error("malloc(%ld) failed.\n", (long)amount);
  181.     wrap_it_up(1);
  182.     }
  183.     return cp;
  184. }
  185.  
  186. /* paranoid version of realloc */
  187. char *
  188. saferealloc(where,size)
  189. char *where;
  190. MEM_SIZE size;
  191. {
  192.     char *ptr;
  193.     char *realloc();
  194.  
  195.     ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  196.     if (ptr == Nullch) {
  197.     log_error("realloc(..., %ld) failed.\n", (long)size);
  198.     wrap_it_up(1);
  199.     }
  200.     return ptr;
  201. }
  202. #endif
  203.  
  204. /* Create a malloc'ed copy of a string. */
  205. char *
  206. savestr(str)
  207. char *str;
  208. {
  209.     register MEM_SIZE len = strlen(str) + 1;
  210.     register char *newaddr = safemalloc(len);
  211.  
  212.     bcopy(str, newaddr, (int)len);
  213.  
  214.     return newaddr;
  215. }
  216.  
  217. #ifndef lint
  218. /* Free some memory if it hasn't already been freed. */
  219. void
  220. safefree(pp)
  221. char **pp;
  222. {
  223.     if (*pp) {
  224.     free(*pp);
  225.     *pp = Nullch;
  226.     }
  227. }
  228. #endif
  229.