home *** CD-ROM | disk | FTP | other *** search
- /* $Id: mt-misc.c,v 3.0 1993/10/01 00:14:02 davison Trn $
- */
- /* The authors make no claims as to the fitness or correctness of this software
- * for any use whatsoever, and it is provided as is. Any use of this software
- * is at the user's own risk.
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "thread.h"
- #include "mthreads.h"
-
- char *newslib, *privlib, *spool, *threaddir, *homedir;
- int locked = 0, cron_locking = 0;
-
- void
- mt_init()
- {
- /* Set up a nice friendly umask. */
- umask(002);
-
- /* Init the directory strings, possibly translating them into real paths */
- homedir = getenv("HOME");
- if (homedir == Nullch) {
- homedir = getenv("LOGDIR");
- }
- spool = savestr(file_exp(NEWSSPOOL));
- newslib = savestr(file_exp(NEWSLIB));
- privlib = savestr(file_exp(PRIVLIB));
- threaddir = file_exp(THREAD_DIR);
- if (strEQ(threaddir,spool))
- threaddir = spool;
- else
- threaddir = savestr(threaddir);
- }
-
- /* Make sure we're not already running by creating a lock file. */
- long
- mt_lock(which_lock, sig)
- int which_lock;
- int sig;
- {
- char buff[LBUFLEN], *filename;
- FILE *fp;
-
- sprintf(buff, "%s.%ld", file_exp(MTPRELOCK), (long)getpid());
- if ((fp = fopen(buff, "w")) == Nullfp) {
- log_entry("Unable to create lock temporary `%s'.\n", buff);
- wrap_it_up(1);
- }
- fprintf(fp, "%s%ld\n", which_lock == DAEMON_LOCK ? "pid " : nullstr,
- (long)getpid());
- fclose(fp);
-
- /* Try to link to lock file. */
- if (which_lock == DAEMON_LOCK) {
- filename = file_exp(MTDLOCK);
- } else {
- filename = file_exp(MTLOCK);
- }
- dolink:
- while (link(buff, filename) < 0) {
- long otherpid;
- if ((fp = fopen(filename, "r")) == Nullfp) {
- log_entry("unable to open %s\n", filename);
- if (cron_locking) {
- goto Sleep;
- }
- unlink(buff);
- wrap_it_up(1);
- }
- if (fscanf(fp, "%ld", &otherpid) != 1) {
- log_entry("unable to read pid from %s\n", filename);
- fclose(fp);
- if (cron_locking) {
- goto Sleep;
- }
- unlink(buff);
- wrap_it_up(1);
- }
- fclose(fp);
- if (kill(otherpid, sig) == -1 && errno == ESRCH) {
- if (unlink(filename) == -1) {
- log_entry("unable to unlink lockfile %s\n", filename);
- unlink(buff);
- wrap_it_up(1);
- }
- goto dolink;
- }
- if (cron_locking) {
- Sleep:
- sleep(60);
- continue;
- }
- unlink(buff);
- return otherpid;
- }
- unlink(buff); /* remove temporary LOCK.<pid> file */
- locked |= which_lock;
- return 0; /* return success */
- }
-
- void
- mt_unlock(which_lock)
- int which_lock;
- {
- which_lock &= locked;
- if (which_lock & PASS_LOCK) {
- unlink(file_exp(MTLOCK)); /* remove single-pass lock */
- }
- if (which_lock & DAEMON_LOCK) {
- unlink(file_exp(MTDLOCK)); /* remove daemon lock */
- }
- locked &= ~which_lock;
- }
-
- /* Interpret rn's %x prefixes and ~name expansions without including tons
- ** of useless source. NOTE: names that don't start with '/', '%' or '~'
- ** are prefixed with the SPOOL directory. (Note that ~'s don't work yet.)
- */
- char *
- file_exp(name)
- char *name;
- {
- static char namebuf[MAXFILENAME];
-
- if (*name == '/') { /* fully qualified names are left alone */
- return name;
- }
- switch (name[0]) {
- case '%': /* interpret certain %x values */
- switch (name[1]) {
- case 'P':
- strcpy(namebuf, spool);
- break;
- case 'W':
- strcpy(namebuf, threaddir);
- break;
- case 'x':
- strcpy(namebuf, newslib);
- break;
- case 'X':
- strcpy(namebuf, privlib);
- break;
- default:
- log_entry("Unknown expansion: %s\n", name);
- wrap_it_up(1);
- }
- strcat(namebuf, name+2);
- break;
- case '~':
- {
- char *s = name + 1;
-
- if (!*s || *s == '/') {
- sprintf(namebuf, "%s%s", homedir, s);
- } else {
- log_entry("~name expansions not implemented.");
- wrap_it_up(1);
- }
- break;
- }
- default: /* all "normal" names are relative to SPOOL */
- sprintf(namebuf, "%s/%s", spool, name);
- break;
- }
- return namebuf;
- }
-
- /* Change a newsgroup name into the name of the thread data file. We
- ** subsitute any '.'s in the group name into '/'s (unless LONG_THREAD_NAMES
- ** is defined), prepend the path, and append the '/.thread' (or '.th') on to
- ** the end.
- */
- char *
- thread_name(group)
- char *group;
- {
- static char name_buf[MAXFILENAME];
- #ifdef LONG_THREAD_NAMES
- sprintf(name_buf, "%s/%s", threaddir, group);
- #else
- register char *cp;
-
- cp = strcpy(name_buf, threaddir) + strlen(threaddir);
- *cp++ = '/';
- strcpy(cp, group);
- while ((cp = index(cp, '.')))
- *cp = '/';
- if (threaddir == spool)
- strcat(name_buf, "/.thread");
- else
- strcat(name_buf, ".th");
- #endif
- return name_buf;
- }
-
- #ifndef lint
- /* A malloc that bombs-out when memory is exhausted. */
- char *
- safemalloc(amount)
- MEM_SIZE amount;
- {
- register char *cp;
-
- if ((cp = malloc(amount)) == Nullch) {
- log_error("malloc(%ld) failed.\n", (long)amount);
- wrap_it_up(1);
- }
- return cp;
- }
-
- /* paranoid version of realloc */
- char *
- saferealloc(where,size)
- char *where;
- MEM_SIZE size;
- {
- char *ptr;
-
- ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
- if (ptr == Nullch) {
- log_error("realloc(..., %ld) failed.\n", (long)size);
- wrap_it_up(1);
- }
- return ptr;
- }
- #endif
-
- /* Create a malloc'ed copy of a string. */
- char *
- savestr(str)
- char *str;
- {
- register MEM_SIZE len = strlen(str) + 1;
- register char *newaddr = safemalloc(len);
-
- bcopy(str, newaddr, (int)len);
-
- return newaddr;
- }
-
- #ifndef lint
- /* Free some memory if it hasn't already been freed. */
- void
- safefree(pp)
- char **pp;
- {
- if (*pp) {
- free(*pp);
- *pp = Nullch;
- }
- }
- #endif
-
- /* Determine this machine's byte map for WORDs and LONGs. A byte map is an
- ** array of BYTEs (sizeof (WORD) or sizeof (LONG) of them) with the 0th BYTE
- ** being the byte number of the high-order byte in my <type>, and so forth.
- */
- void
- mybytemap(map)
- BMAP *map;
- {
- union {
- BYTE b[sizeof (LONG)];
- WORD w;
- LONG l;
- } u;
- register BYTE *mp;
- register int i, j;
-
- mp = &map->w[sizeof (WORD)];
- u.w = 1;
- for (i = sizeof (WORD); i > 0; i--) {
- for (j = 0; j < sizeof (WORD); j++) {
- if (u.b[j] != 0) {
- break;
- }
- }
- if (j == sizeof (WORD)) {
- goto bad_news;
- }
- *--mp = j;
- while (u.b[j] != 0 && u.w) {
- u.w <<= 1;
- }
- }
-
- mp = &map->l[sizeof (LONG)];
- u.l = 1;
- for (i = sizeof (LONG); i > 0; i--) {
- for (j = 0; j < sizeof (LONG); j++) {
- if (u.b[j] != 0) {
- break;
- }
- }
- if (j == sizeof (LONG)) {
- bad_news:
- /* trouble -- set both to *something* consistent */
- for (j = 0; j < sizeof (WORD); j++) {
- map->w[j] = j;
- }
- for (j = 0; j < sizeof (LONG); j++) {
- map->l[j] = j;
- }
- return;
- }
- *--mp = j;
- while (u.b[j] != 0 && u.l) {
- u.l <<= 1;
- }
- }
- }
-
- /* Transform each WORD's byte-ordering in a buffer of the designated length.
- */
- void
- wp_bmap(buf, len)
- WORD *buf;
- int len;
- {
- union {
- BYTE b[sizeof (WORD)];
- WORD w;
- } in, out;
- register int i;
-
- if (word_same) {
- return;
- }
- while (len--) {
- in.w = *buf;
- for (i = 0; i < sizeof (WORD); i++) {
- out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
- }
- *buf++ = out.w;
- }
- }
-
- /* Transform each LONG's byte-ordering in a buffer of the designated length.
- */
- void
- lp_bmap(buf, len)
- LONG *buf;
- int len;
- {
- union {
- BYTE b[sizeof (LONG)];
- LONG l;
- } in, out;
- register int i;
-
- if (long_same) {
- return;
- }
- while (len--) {
- in.l = *buf;
- for (i = 0; i < sizeof (LONG); i++) {
- out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
- }
- *buf++ = out.l;
- }
- }
-