home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
trn_12.zip
/
src
/
acttimes.c
next >
Wrap
C/C++ Source or Header
|
1993-11-08
|
15KB
|
513 lines
/* $Header: acttimes.c,v 1.1 91/11/02 18:38:29 davison Exp $
**
** $Log: acttimes.c,v $
*/
/* This program will maintain the file active.times if your news software
** doesn't already do this for you. The file contains a list of newsgroup
** names followed by the time of creation (in seconds since 1970) and the
** address of the creator. Since we can't tell who actually created the
** group, they will all indicate acttimes@DOMAIN.
**
** Place this file in your NNTP support directory and change your
** common/conf.h to undef NGDATE_FILE and STAT_FILE, and define
** ACTIVE_TIMES_FILE. To make, you can replace every mention of
** "mkgrdates" in the support/Makefile with "acttimes" and then
** type "make".
**
** To use this without having NNTP around, undefine the NNTP_SUPPORT
** define, edit the other defines that follow to indicate your setup,
** and compile it with something like "cc -O -o acttimes acttimes.c".
**
** Use either "acttimes -d" to start a daemon process that wakes up every
** 10 minutes (by default) to check if the active file is a different
** size, or put "acttimes" into your cron file to be run periodically.
*/
/*** OS2: no NNTP ***/
#undef NNTP_SUPPORT /* comment out if not using NNTP */
/*** OS2: there are links used in the source, but the
OS/2-file-systems don't have them. We try to
avoid them via the DosCopy-systemcall ***/
#include <os2.h>
/*** OS2: chdir does not change the workingdrive if required,
but the news gcc-call _chdir2 does this. ***/
#ifndef _CHDIR2_DEF
#define _CHDIR2_DEF
#define chdir _chdir2
#define getcwd _getcwd2
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
/*** OS2: for the check of the uupc-rc-files, we need
the os2patch-files ***/
#include "os2patch.h"
#ifdef NNTP_SUPPORT
#include "../common/conf.h"
#endif
#ifdef USG
#include <time.h>
#else
#include <sys/time.h>
#endif
/* ---------- Start of configuration defines ---------- */
/*** OS2: yes, we have TERMIO ***/
/*#ifndef USG*/
#define TERMIO /* Is this is termio system? */
/*#endif*/
/* NNTP sites have the following already defined in ../common/conf.h */
#ifndef DOMAIN /* our domain name */
#define DOMAIN "local"
#endif
#ifndef ACTIVE_FILE /* the active file for your news system */
/** OS2: patch **/
#define ACTIVE_FILE uupc_rc_settings.active
#endif
#ifndef ACTIVE_OPT_FILE /* the active file for your news system */
/** OS2: patch **/
#define ACTIVE_OPT_FILE uupc_rc_settings.active_opt
#endif
#ifndef ACTIVE_TIMES_FILE /* the name of the file to update */
/** OS2: patch **/
#define ACTIVE_TIMES_FILE uupc_rc_settings.active_times
#endif
#ifndef SIGRET /* set this to "int" if you have problems */
#define SIGRET void
#endif
#ifndef MAXPATHLEN /* you'll probably want to leave this alone */
#define MAXPATHLEN 1024
#endif
/*#define index strchr /* uncomment these if you need them */
/*#define rindex strrchr /* (i.e. if index is undefined) */
/* ---------- End of configuration defines ---------- */
#ifdef TERMIO
#include <termio.h>
#else
#include <sgtty.h>
#endif
#define TIMER_FIRST 1
#define TIMER_DEFAULT (10 * 60)
#define strnEQ(x,y,n) (!strncmp((x),(y),(n)))
extern errno;
char *index(), *rindex(), *malloc();
SIGRET alarm_handler(), quit_handler();
void active_times(), free_lines(), wrap_it_up();
typedef struct _active_line {
struct _active_line *link;
char *name;
char type;
} ACTIVE_LINE;
ACTIVE_LINE *line_root = NULL, *last_line = NULL, *pline = NULL;
long last_actsize;
int daemon_delay = 0, kill_daemon = 0, old_groups = 0;
FILE *fp_lock;
struct stat filestat;
char buf[MAXPATHLEN];
char lockfile[MAXPATHLEN];
main(argc, argv)
int argc;
char *argv[];
{
int fd;
long pid;
char *cp;
/*** OS2: Now we load the settings out of the uupc-rc-files.
This settings contain the information, which was
previously hardcoded in the config.h-file by
the Configure-shell-script. ***/
if (!load_uupc_rc())
{ fprintf(stderr,"An error occurred while reading the uupc-rc-files!\n\
The following settings must be defined in the UUPCSYSRC-file:\n\
MailServ, NodeName, NewsDir, Domain, TempDir, MailDir, rmail\n");
fprintf(stderr,"These settings must be defined in the UUPCUSRRC-file:\n\
Mailbox, Signature, Name, Home, Organization, Editor\n");
fprintf(stderr,"And these settings must be defined in the UUPCTRNRC-file:\n\
Newsadmin, TrnLib, LocalDist, OrganizationDist, CityDist,\n\
StateDist, Countrydist, ContinentDist\n");
fprintf(stderr,"\nDon't forget, these settings are required, not optional!\n");
fflush(stderr);
exit(1);
}
while (--argc) {
if (**++argv == '-') {
while (*++*argv) {
switch (**argv) {
case 'd': /* run in daemon mode */
/*** OS2: I'm sorry, but we will not run in daemon mode, because
emx 0.8d does not support fork's at the moment. **/
if (*++*argv <= '9' && **argv >= '0') {
daemon_delay = atoi(*argv) * 60;
while (*++*argv <= '9' && **argv >= '0') {
;
}
} else {
daemon_delay = TIMER_DEFAULT;
}
--*argv;
break;
case 'k': /* kill running acttimes */
kill_daemon++;
break;
default:
fprintf(stderr, "Unknown option: '%c'\n", **argv);
exit(1);
}
}
} else {
fprintf(stderr,
"Usage: acttimes [-d<mins>]\nOr: acttimes -k\n");
exit(1);
}
}
/* Set up a nice friendly umask. */
umask(002);
/* Make sure we're not already running by creating a lock file. */
strcpy(lockfile, ACTIVE_TIMES_FILE);
if ((cp = rindex(lockfile, '/')) != 0) {
cp++;
} else {
cp = lockfile;
}
*cp = '\0';
sprintf(buf, "%sLOCK.%ld", lockfile, (long)getpid());
if ((fp_lock = fos2open(buf, "w")) == 0) {
fprintf(stderr, "Unable to create lock temporary `%s'.\n", buf);
exit(1);
}
fprintf(fp_lock, "%ld\n", (long)getpid());
fclose(fp_lock);
/* Try to link to lock file. */
strcat(lockfile, "LOCKacttimes");
dolink:
/*** OS2: This is a bit of a problem, because the DosCopy
is perhaps not the solution for this link, but I
think if there is no daemon mode, and if we don't
run the program twice simultameously, the DosCopy will do ***/
/* if (link(buf, lockfile) < 0) { */
if (DosCopy(buf, lockfile, DCPY_EXISTING)) {
long otherpid;
/* Try to avoid possible race with daemon starting up. */
sleep (5);
if ((fp_lock = fos2open(lockfile, "r")) == 0) {
fprintf(stderr, "unable to open %s\n", lockfile);
unlink(buf);
exit(1);
}
if (fscanf(fp_lock, "%ld", &otherpid) != 1) {
fprintf(stderr, "unable to read pid from %s\n", lockfile);
unlink(buf);
fclose(fp_lock);
exit(1);
}
fclose(fp_lock);
if (kill(otherpid, kill_daemon ? SIGTERM : 0) == -1
&& errno == ESRCH) {
if (unlink(lockfile) == -1) {
fprintf(stderr, "unable to unlink lockfile %s\n", lockfile);
unlink(buf);
exit(1);
}
if (!kill_daemon) {
goto dolink;
}
}
unlink(buf);
if (kill_daemon) {
fprintf(stderr, "killing currently running acttimes.\n");
exit(0);
} else {
fprintf(stderr, "acttimes is already running.\n");
exit(1);
}
}
unlink(buf); /* remove temporary LOCK.<pid> file */
if (kill_daemon) {
fprintf(stderr, "acttimes is not running.\n");
wrap_it_up(1);
}
#ifdef SIGHUP
if( signal( SIGHUP, SIG_IGN ) != SIG_IGN ) {
signal( SIGHUP, quit_handler );
}
#endif
if( signal( SIGINT, SIG_IGN ) != SIG_IGN ) {
signal( SIGINT, quit_handler );
}
#ifdef SIGQUIT
if( signal( SIGQUIT, SIG_IGN ) != SIG_IGN ) {
signal( SIGQUIT, quit_handler );
}
#endif
signal( SIGTERM, quit_handler );
#ifdef SIGTTIN
signal( SIGTTIN, SIG_IGN );
signal( SIGTTOU, SIG_IGN );
#endif
signal( SIGALRM, SIG_IGN );
/* If we're not in daemon mode, run through once and quit. */
/*** OS2: we don't use daemon mode, because of the fork's ***/
daemon_delay = 0;
if (!daemon_delay) {
active_times();
} else {
/* For daemon mode, we cut ourself off from anything tty-related and
** run in the background (involves forks, but no knives).
*/
close(0);
if (open("/dev/null", 2) != 0) {
fprintf(stderr, "unable to open /dev/null!\n");
wrap_it_up(1);
}
close(1);
close(2);
dup(0);
dup(0);
/*** OS2: no daemon, no fork ***/
/* while ((pid = fork()) < 0) { */
/* sleep(2); */
/* } */
/* if (pid) { */
/* exit(0); */
/* } */
/*#ifdef TIOCNOTTY */
/* if ((fd = open("/dev/tty", 1)) >= 0) { */
/* ioctl(fd, TIOCNOTTY, (int*)0); */
/* close(fd); */
/* } */
/*#else */
/* (void) setpgrp(); */
/* while ((pid = fork()) < 0) { */
/* sleep(2); */
/* } */
/* if (pid) { */
/* exit(0); */
/* } */
/*#endif */
/* Put our pid in the lock file for death detection */
if( (fp_lock = fos2open(lockfile, "w")) != 0) {
fprintf(fp_lock, "%ld\n", (long)getpid());
fclose(fp_lock);
}
signal(SIGALRM, alarm_handler);
/* Start timer -- first interval is shorter than all others */
alarm(TIMER_FIRST);
for (;;) {
/*** OS2: no daemon, no pause ***/
/* pause(); /* let alarm go off */
alarm(0);
if (stat(ACTIVE_FILE, &filestat) < 0) {
if (stat(ACTIVE_OPT_FILE, &filestat) < 0) {
fprintf(stderr, "Unable to stat active file -- quitting.\n");
wrap_it_up(1);
}
}
if (filestat.st_size != last_actsize) {
last_actsize = filestat.st_size;
active_times();
}
alarm(daemon_delay);
} /* for */
}/* if */
wrap_it_up(0);
}
SIGRET
alarm_handler()
{
signal(SIGALRM, alarm_handler);
}
SIGRET
quit_handler()
{
wrap_it_up(0);
}
void
wrap_it_up(ret)
{
unlink(lockfile);
exit(ret);
}
void
active_times()
{
FILE *fp_active, *fp_date_r, *fp_date_w;
register char *cp;
if ((fp_active = fos2open(ACTIVE_FILE, "r")) == NULL) {
if ((fp_active = fos2open(ACTIVE_OPT_FILE, "r")) == NULL) {
if (!daemon_delay) {
fprintf(stderr, "Unable to open active file.\n");
}
return;
}
}
if ((fp_date_r = fos2open(ACTIVE_TIMES_FILE, "r")) == NULL) {
if (!daemon_delay) {
fprintf(stderr, "Creating active.times file.\n");
}
old_groups = 1;
} else {
old_groups = 0;
}
sprintf(buf, "%s.n", ACTIVE_TIMES_FILE);
if ((fp_date_w = fos2open(buf, "w")) == NULL) {
if (!daemon_delay) {
fprintf(stderr, "Unable to create active.times file.\n");
}
return;
}
/* Loop through entire active file and remember each line. */
while (fgets(buf, sizeof buf, fp_active)) {
if (!(cp = index(buf, ' ')) || cp[1] == '\0') {
continue;
}
cp[1] = '\0'; /* include trailing space */
if (!(cp = rindex(cp + 2, ' '))) {
continue;
}
pline = (ACTIVE_LINE*)malloc(sizeof (ACTIVE_LINE));
if (!pline) {
if (line_root) {
last_line->link = NULL;
free_lines();
}
bug_out:
fclose(fp_active);
fclose(fp_date_r);
fclose(fp_date_w);
return;
}
pline->name = malloc(strlen(buf) + 1);
if (!pline->name) {
if (line_root) {
last_line->link = NULL;
pline->name = NULL;
free_lines();
} else {
free(pline);
}
goto bug_out;
}
strcpy(pline->name, buf);
pline->type = cp[1];
if (!last_line) {
line_root = pline;
} else {
last_line->link = pline;
}
last_line = pline;
}
last_line->link = NULL;
fclose(fp_active);
if (fp_date_r) {
/* Loop through date file, copying existing groups to new file. */
while (fgets(buf, sizeof buf, fp_date_r)) {
last_line = NULL;
for (pline = line_root; pline; pline = pline->link) {
if (strnEQ(buf, pline->name, strlen(pline->name))) {
fputs(buf, fp_date_w);
free(pline->name);
if (last_line) {
last_line->link = pline->link;
} else {
line_root = pline->link;
}
free(pline);
break;
}
last_line = pline;
}/* for */
}
}
/* Remaining entries from active file are new groups. */
for (pline = line_root; pline; pline = last_line) {
if (pline->type != 'x' && pline->type != '=') {
/* If it's not 'x'ed out, write it out with the current time. */
fprintf(fp_date_w, "%s%ld acttimes@%s\n", pline->name,
old_groups ? 30010440L : time(NULL), DOMAIN);
}
free(pline->name);
last_line = pline->link;
free(pline);
}
fclose(fp_date_w);
if (fp_date_r != NULL) fclose(fp_date_r);
line_root = NULL;
/* rm active.times.o */
sprintf(buf,"%s.o", ACTIVE_TIMES_FILE);
unlink(buf);
/* mv active.times active.times.o */
/*** OS2: this is not very difficult to patch, the combination
of link/unlink is a save rename. Use DosCopy or rename ***/
/** link(ACTIVE_TIMES_FILE, buf); **/
DosCopy(ACTIVE_TIMES_FILE, buf, DCPY_EXISTING);
unlink(ACTIVE_TIMES_FILE);
/* mv active.times.n active.times */
sprintf(buf, "%s.n", ACTIVE_TIMES_FILE);
/** link(buf, ACTIVE_TIMES_FILE); **/
DosCopy(buf, ACTIVE_TIMES_FILE, DCPY_EXISTING);
unlink(buf);
}
void
free_lines()
{
for (pline = line_root; pline; pline = last_line) {
if (pline->name) {
free(pline->name);
}
last_line = pline->link;
free(pline);
}
line_root = NULL;
}