/*
 * LIB/EXPIRE.C
 *
 * (c)Copyright 1997, Matthew Dillon, All Rights Reserved.  Refer to
 *    the COPYRIGHT file in the base directory of this distribution 
 *    for specific rights granted.
 */

#include "defs.h"

#include <sys/param.h>
#ifndef _AIX
#include <sys/mount.h>
#endif
#ifdef _AIX
#include <sys/statfs.h>
#endif

#if USE_SYSV_STATFS
#include <sys/statfs.h>
#define f_bavail f_bfree
#endif

/*
 * The solaris statvfs is rather limited, but we suffer with reduced
 * capability (and hence take a possible performance hit).
 */
#if USE_SUN_STATVFS
#include <sys/statvfs.h>        /* god knows if this hack will work */
#define f_bsize f_frsize        /* god knows if this hack will work */
#define fsid_t u_long
#define statfs statvfs
#endif

#if USE_SYS_VFS                 /* this is mainly for linux     */
#include <sys/vfs.h>
#endif

Prototype int GetOverExpire(const char *groupName, OverExpire *oe);
Prototype void LoadExpireCtl(int force);

OverExpire *OvExBase = NULL;
MemPool *EXMemPool = NULL;

uint32 ExGmtMin = (uint32)-1;
time_t ExMTime = 0;

void dumpOvExpire(OverExpire *ov);

/*
 * Return the overview expire in seconds and the overview expire
 * entry for the specified group
 */
int
GetOverExpire(const char *groupName, OverExpire *oe)
{
    int found = 0;
    OverExpire *toe;

    memset(oe, 0, sizeof(OverExpire));
    for (toe = OvExBase; toe; toe = toe->oe_Next) {
	if (WildCmp(toe->oe_Wild, groupName) == 0) {
	    found = 1;
	    memcpy(oe, toe, sizeof(OverExpire));
	}
    }
    if (DebugOpt > 5)
	dumpOvExpire(oe);
    return(oe->oe_ExpireDays * 24.0 * 60.0 * 60.0);
}

void
loadExpireCtl(FILE *fi)
{
    char buf[MAXGNAME+256];
    int line = 0;
    OverExpire **pov = &OvExBase;

    if (DebugOpt)
	printf("Loading dexpire.ctl\n");

    freePool(&EXMemPool);
    while (fi && fgets(buf, sizeof(buf), fi) != NULL) {
	char *p = buf;
	char *q = buf;

	line++;
	while (isspace((int)*p))
	    p++;
	if (!*p || *p == '/' || *p == '#')
	    continue;

	if ((q = strchr(p, ':')) != NULL) {
	    OverExpire *ov = zalloc(&EXMemPool,
					sizeof(OverExpire) + (q - p) + 1);
	    ov->oe_ExpireDays = -1.0;
	    ov->oe_InitArts = 512;
	    ov->oe_MinArts = 24;
	    ov->oe_MaxArts = 0;


	    memmove(&ov->oe_Wild, buf, q - p);
	    ov->oe_Wild[q-p] = 0;
	    *pov = ov;
	    pov = &ov->oe_Next;

	    q = p;
	    while ((q = strchr(q + 1, ':')) != NULL) {
		switch(q[1]) {
		    case 'a':
			ov->oe_InitArts = strtol(q + 2, NULL, 0);
			break;
		    case 'i':
			ov->oe_MinArts = strtol(q + 2, NULL, 0);
			break;
		    case 'j':
			ov->oe_MaxArts = strtol(q + 2, NULL, 0);
			break;
		    case 'x':
			ov->oe_ExpireDays = strtod(q + 2, NULL);
			break;
		}
	    }
	}
    }
    *pov = NULL;
}

/*
 * Load dexpire.ctl - overview expiry info
 */
void
LoadExpireCtl(int force)
{
    time_t gmt = time(NULL) / 60;

    /*
     * check for dspool.ctl file modified once a minute
     */

    if (force || gmt != ExGmtMin) {
	struct stat st = { 0 };

	ExGmtMin = gmt;

	/*
	 * dexpire.ctl
	 */

	{
	    FILE *fi;

	    fi = fopen(PatLibExpand(DExpireCtlPat), "r");

	    if (fi == NULL) {
		logit(LOG_CRIT, "%s file not found",
					PatLibExpand(DExpireCtlPat));
		exit(1);
	    }

	    if (force || fi == NULL || 
		(fstat(fileno(fi), &st) == 0 && st.st_mtime != ExMTime)
	    ) {
		if (force)
		    fstat(fileno(fi), &st);
		ExMTime = st.st_mtime;	/* may be 0 if file failed to open */
		loadExpireCtl(fi);
	    }
	    if (fi)
		fclose(fi);
	}
    }
}

void
dumpOvExpire(OverExpire *ov)
{
    printf("%s:%.2f:%d:%d:%d\n", ov->oe_Wild,
				ov->oe_ExpireDays,
				ov->oe_InitArts,
				ov->oe_MinArts,
				ov->oe_MaxArts);
}


syntax highlighted by Code2HTML, v. 0.9.1