home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / mthreads / part01 / mt-misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-20  |  7.4 KB  |  364 lines

  1. /* $Id: mt-misc.c,v 3.0 1993/10/01 00:14:02 davison Trn $
  2. */
  3. /* The authors make no claims as to the fitness or correctness of this software
  4.  * for any use whatsoever, and it is provided as is. Any use of this software
  5.  * is at the user's own risk. 
  6.  */
  7.  
  8. #include "EXTERN.h"
  9. #include "common.h"
  10. #include "thread.h"
  11. #include "mthreads.h"
  12.  
  13. char *newslib, *privlib, *spool, *threaddir, *homedir;
  14. int locked = 0, cron_locking = 0;
  15.  
  16. void
  17. mt_init()
  18. {
  19.     /* Set up a nice friendly umask. */
  20.     umask(002);
  21.  
  22.     /* Init the directory strings, possibly translating them into real paths */
  23.     homedir = getenv("HOME");
  24.     if (homedir == Nullch) {
  25.     homedir = getenv("LOGDIR");
  26.     }
  27.     spool = savestr(file_exp(NEWSSPOOL));
  28.     newslib = savestr(file_exp(NEWSLIB));
  29.     privlib = savestr(file_exp(PRIVLIB));
  30.     threaddir = file_exp(THREAD_DIR);
  31.     if (strEQ(threaddir,spool))
  32.     threaddir = spool;
  33.     else
  34.     threaddir = savestr(threaddir);
  35. }
  36.  
  37. /* Make sure we're not already running by creating a lock file. */
  38. long
  39. mt_lock(which_lock, sig)
  40. int which_lock;
  41. int sig;
  42. {
  43.     char buff[LBUFLEN], *filename;
  44.     FILE *fp;
  45.  
  46.     sprintf(buff, "%s.%ld", file_exp(MTPRELOCK), (long)getpid());
  47.     if ((fp = fopen(buff, "w")) == Nullfp) {
  48.     log_entry("Unable to create lock temporary `%s'.\n", buff);
  49.     wrap_it_up(1);
  50.     }
  51.     fprintf(fp, "%s%ld\n", which_lock == DAEMON_LOCK ? "pid " : nullstr,
  52.     (long)getpid());
  53.     fclose(fp);
  54.  
  55.     /* Try to link to lock file. */
  56.     if (which_lock == DAEMON_LOCK) {
  57.     filename = file_exp(MTDLOCK);
  58.     } else {
  59.     filename = file_exp(MTLOCK);
  60.     }
  61.   dolink:
  62.     while (link(buff, filename) < 0) {
  63.       long otherpid;
  64.     if ((fp = fopen(filename, "r")) == Nullfp) {
  65.         log_entry("unable to open %s\n", filename);
  66.         if (cron_locking) {
  67.         goto Sleep;
  68.         }
  69.         unlink(buff);
  70.         wrap_it_up(1);
  71.     }
  72.     if (fscanf(fp, "%ld", &otherpid) != 1) { 
  73.         log_entry("unable to read pid from %s\n", filename);
  74.         fclose(fp);
  75.         if (cron_locking) {
  76.         goto Sleep;
  77.         }
  78.         unlink(buff);
  79.         wrap_it_up(1);
  80.     }
  81.     fclose(fp);
  82.     if (kill(otherpid, sig) == -1 && errno == ESRCH) {
  83.         if (unlink(filename) == -1) {
  84.         log_entry("unable to unlink lockfile %s\n", filename);
  85.         unlink(buff);
  86.         wrap_it_up(1);
  87.         }
  88.         goto dolink;
  89.     }
  90.     if (cron_locking) {
  91.       Sleep:
  92.         sleep(60);
  93.         continue;
  94.     }
  95.     unlink(buff);
  96.     return otherpid;
  97.     }
  98.     unlink(buff);            /* remove temporary LOCK.<pid> file */
  99.     locked |= which_lock;
  100.     return 0;                /* return success */
  101. }
  102.  
  103. void
  104. mt_unlock(which_lock)
  105. int which_lock;
  106. {
  107.     which_lock &= locked;
  108.     if (which_lock & PASS_LOCK) {
  109.     unlink(file_exp(MTLOCK));        /* remove single-pass lock */
  110.     }
  111.     if (which_lock & DAEMON_LOCK) {
  112.     unlink(file_exp(MTDLOCK));        /* remove daemon lock */
  113.     }
  114.     locked &= ~which_lock;
  115. }
  116.  
  117. /* Interpret rn's %x prefixes and ~name expansions without including tons
  118. ** of useless source.  NOTE:  names that don't start with '/', '%' or '~'
  119. ** are prefixed with the SPOOL directory.  (Note that ~'s don't work yet.)
  120. */
  121. char *
  122. file_exp(name)
  123. char *name;
  124. {
  125.     static char namebuf[MAXFILENAME];
  126.  
  127.     if (*name == '/') {    /* fully qualified names are left alone */
  128.     return name;
  129.     }
  130.     switch (name[0]) {
  131.     case '%':            /* interpret certain %x values */
  132.     switch (name[1]) {
  133.     case 'P':
  134.         strcpy(namebuf, spool);
  135.         break;
  136.     case 'W':
  137.         strcpy(namebuf, threaddir);
  138.         break;
  139.     case 'x':
  140.         strcpy(namebuf, newslib);
  141.         break;
  142.     case 'X':
  143.         strcpy(namebuf, privlib);
  144.         break;
  145.     default:
  146.         log_entry("Unknown expansion: %s\n", name);
  147.         wrap_it_up(1);
  148.     }
  149.     strcat(namebuf, name+2);
  150.     break;
  151.     case '~':
  152.     {
  153.     char *s = name + 1;
  154.  
  155.     if (!*s || *s == '/') {
  156.         sprintf(namebuf, "%s%s", homedir, s);
  157.     } else {
  158.         log_entry("~name expansions not implemented.");
  159.         wrap_it_up(1);
  160.     }
  161.     break;
  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. /* Change a newsgroup name into the name of the thread data file.  We
  171. ** subsitute any '.'s in the group name into '/'s (unless LONG_THREAD_NAMES
  172. ** is defined), prepend the path, and append the '/.thread' (or '.th') on to
  173. ** the end.
  174. */
  175. char *
  176. thread_name(group)
  177. char *group;
  178. {
  179.     static char name_buf[MAXFILENAME];
  180. #ifdef LONG_THREAD_NAMES
  181.     sprintf(name_buf, "%s/%s", threaddir, group);
  182. #else
  183.     register char *cp;
  184.  
  185.     cp = strcpy(name_buf, threaddir) + strlen(threaddir);
  186.     *cp++ = '/';
  187.     strcpy(cp, group);
  188.     while ((cp = index(cp, '.')))
  189.     *cp = '/';
  190.     if (threaddir == spool)
  191.     strcat(name_buf, "/.thread");
  192.     else
  193.     strcat(name_buf, ".th");
  194. #endif
  195.     return name_buf;
  196. }
  197.  
  198. #ifndef lint
  199. /* A malloc that bombs-out when memory is exhausted. */
  200. char *
  201. safemalloc(amount)
  202. MEM_SIZE amount;
  203. {
  204.     register char *cp;
  205.  
  206.     if ((cp = malloc(amount)) == Nullch) {
  207.     log_error("malloc(%ld) failed.\n", (long)amount);
  208.     wrap_it_up(1);
  209.     }
  210.     return cp;
  211. }
  212.  
  213. /* paranoid version of realloc */
  214. char *
  215. saferealloc(where,size)
  216. char *where;
  217. MEM_SIZE size;
  218. {
  219.     char *ptr;
  220.  
  221.     ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  222.     if (ptr == Nullch) {
  223.     log_error("realloc(..., %ld) failed.\n", (long)size);
  224.     wrap_it_up(1);
  225.     }
  226.     return ptr;
  227. }
  228. #endif
  229.  
  230. /* Create a malloc'ed copy of a string. */
  231. char *
  232. savestr(str)
  233. char *str;
  234. {
  235.     register MEM_SIZE len = strlen(str) + 1;
  236.     register char *newaddr = safemalloc(len);
  237.  
  238.     bcopy(str, newaddr, (int)len);
  239.  
  240.     return newaddr;
  241. }
  242.  
  243. #ifndef lint
  244. /* Free some memory if it hasn't already been freed. */
  245. void
  246. safefree(pp)
  247. char **pp;
  248. {
  249.     if (*pp) {
  250.     free(*pp);
  251.     *pp = Nullch;
  252.     }
  253. }
  254. #endif
  255.  
  256. /* Determine this machine's byte map for WORDs and LONGs.  A byte map is an
  257. ** array of BYTEs (sizeof (WORD) or sizeof (LONG) of them) with the 0th BYTE
  258. ** being the byte number of the high-order byte in my <type>, and so forth.
  259. */
  260. void
  261. mybytemap(map)
  262. BMAP *map;
  263. {
  264.     union {
  265.     BYTE b[sizeof (LONG)];
  266.     WORD w;
  267.     LONG l;
  268.     } u;
  269.     register BYTE *mp;
  270.     register int i, j;
  271.  
  272.     mp = &map->w[sizeof (WORD)];
  273.     u.w = 1;
  274.     for (i = sizeof (WORD); i > 0; i--) {
  275.     for (j = 0; j < sizeof (WORD); j++) {
  276.         if (u.b[j] != 0) {
  277.         break;
  278.         }
  279.     }
  280.     if (j == sizeof (WORD)) {
  281.         goto bad_news;
  282.     }
  283.     *--mp = j;
  284.     while (u.b[j] != 0 && u.w) {
  285.         u.w <<= 1;
  286.     }
  287.     }
  288.  
  289.     mp = &map->l[sizeof (LONG)];
  290.     u.l = 1;
  291.     for (i = sizeof (LONG); i > 0; i--) {
  292.     for (j = 0; j < sizeof (LONG); j++) {
  293.         if (u.b[j] != 0) {
  294.         break;
  295.         }
  296.     }
  297.     if (j == sizeof (LONG)) {
  298.       bad_news:
  299.         /* trouble -- set both to *something* consistent */
  300.         for (j = 0; j < sizeof (WORD); j++) {
  301.         map->w[j] = j;
  302.         }
  303.         for (j = 0; j < sizeof (LONG); j++) {
  304.         map->l[j] = j;
  305.         }
  306.         return;
  307.     }
  308.     *--mp = j;
  309.     while (u.b[j] != 0 && u.l) {
  310.         u.l <<= 1;
  311.     }
  312.     }
  313. }
  314.  
  315. /* Transform each WORD's byte-ordering in a buffer of the designated length.
  316. */
  317. void
  318. wp_bmap(buf, len)
  319. WORD *buf;
  320. int len;
  321. {
  322.     union {
  323.     BYTE b[sizeof (WORD)];
  324.     WORD w;
  325.     } in, out;
  326.     register int i;
  327.  
  328.     if (word_same) {
  329.     return;
  330.     }
  331.     while (len--) {
  332.     in.w = *buf;
  333.     for (i = 0; i < sizeof (WORD); i++) {
  334.         out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
  335.     }
  336.     *buf++ = out.w;
  337.     }
  338. }
  339.  
  340. /* Transform each LONG's byte-ordering in a buffer of the designated length.
  341. */
  342. void
  343. lp_bmap(buf, len)
  344. LONG *buf;
  345. int len;
  346. {
  347.     union {
  348.     BYTE b[sizeof (LONG)];
  349.     LONG l;
  350.     } in, out;
  351.     register int i;
  352.  
  353.     if (long_same) {
  354.     return;
  355.     }
  356.     while (len--) {
  357.     in.l = *buf;
  358.     for (i = 0; i < sizeof (LONG); i++) {
  359.         out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
  360.     }
  361.     *buf++ = out.l;
  362.     }
  363. }
  364.