This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/msgidlib/genmsgid.c
2005-10-23 04:39:25 +00:00

187 lines
5.9 KiB
C
Executable File

/* This is modifyed part of HUSKY project */
/*
* HUSKYLIB: common defines, types and functions for HUSKY
*
* This is part of The HUSKY Fidonet Software project:
* see http://husky.sourceforge.net for details
*
*
* HUSKYLIB is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* HUSKYLIB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see file COPYING. If not, write to the
* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* See also http://www.gnu.org, license may be found here.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if !defined(UNIX) && !defined(SASC)
# include <io.h>
#endif
#if defined(UNIX) || defined(__DJGPP__) || defined(__EMX__)
# include <unistd.h>
#endif
#if defined(UNIX)
#define stricmp strcasecmp
#endif
#include "hsksupp.h"
#include "ffind.h"
#define MAX_OUTRUN (3ul*365*24*60*60) /* 3 year */
#define GenMsgIdErr(a) { if (errstr!=NULL) { *errstr = a; } }
dword oldGenMsgId(void)
{
dword seq = (dword)time(NULL);
sleep(1);
return seq;
}
dword GenMsgIdEx(char *seqdir, unsigned long max_outrun, dword (*altGenMsgId)(void), char **errstr)
{
dword seq, n, curtime;
FFIND *ff;
char *seqpath, max_fname[13], *new_fname, *pname, *p;
int h, try;
if (altGenMsgId == NULL)
altGenMsgId = oldGenMsgId;
GenMsgIdErr(NULL);
if (seqdir == NULL || *seqdir == '\0') {
seqdir = getenv("SEQDIR");
if (seqdir == NULL || *seqdir == '\0') {
/* warning: no SEQDIR defined, fall to ugly old algorythm */
GenMsgIdErr("no SEQDIR defined");
return (*altGenMsgId)();
}
}
seqpath = malloc(strlen(seqdir)+13);
strcpy(seqpath, seqdir);
pname = seqpath + strlen(seqpath);
if (*seqpath && strchr("/\\", seqpath[strlen(seqpath)-1]) == NULL)
*pname++ = PATH_DELIM;
new_fname = NULL;
if (max_outrun == 0) {
p = getenv("SEQOUT");
if ( p && isdigit((int)(*p)) ) {
max_outrun = (unsigned long)atol(p);
switch (tolower(p[strlen(p) - 1])) {
case 'y': max_outrun *= 365;
case 'd': max_outrun *= 24;
case 'h': max_outrun *= 60*60;
break;
case 'w': max_outrun *= (7l*24*60*60);
break;
case 'm': max_outrun *= (31l*24*60*60);
break;
}
}
else max_outrun = MAX_OUTRUN;
}
for (try=0;;try++) {
curtime = (dword)time(NULL);
seq = 0;
max_fname[0] = '\0';
strcpy(pname, "*.*");
ff = FFindOpen(seqpath, 0);
if (ff == NULL) { /* file not found */
*pname = '\0';
if (try == 0) {
if (direxist(seqpath))
goto emptydir; /* directory exist & empty */
else if (_createDirectoryTree(seqpath) == 0)
goto emptydir; /* directory created */
} /* if directory not created at 1st time then use old alghorithm */
free(seqpath);
if (new_fname) free(new_fname);
GenMsgIdErr("can't open/create SEQDIR directory");
return (*altGenMsgId)();
}
do {
for (p=ff->ff_name; isxdigit((int)(*p)); p++);
if (stricmp(p, ".seq") != 0) continue;
if (strlen(ff->ff_name) > 12) continue;
n = strtol(ff->ff_name, NULL, 16);
if (n > curtime && n - curtime > max_outrun) {
/* counter too large, remove */
strcpy(pname, ff->ff_name);
unlink(seqpath);
continue;
}
if (n >= seq) {
if (max_fname[0]) {
strcpy(pname, max_fname);
unlink(seqpath);
}
strcpy(max_fname, ff->ff_name);
seq = n;
} else {
strcpy(pname, ff->ff_name);
unlink(seqpath);
}
} while (FFindNext(ff) == 0);
if (ff) FFindClose(ff);
emptydir:
if (seq < curtime) seq = curtime;
if (new_fname == NULL)
new_fname = malloc(strlen(seqpath) + 13);
*pname = '\0';
sprintf(new_fname, "%s%08lx.seq", seqpath, (unsigned long)(seq + 1));
if (max_fname[0] == '\0') {
/* No files found, create new */
h = open(new_fname, O_CREAT|O_BINARY|O_EXCL, 0666);
if (h != -1) {
/* ok, scan again */
close(h);
continue;
}
/* error creating file */
if (errno == EEXIST) continue;
free(seqpath);
free(new_fname);
GenMsgIdErr("error creating file in SEQDIR directory");
return (*altGenMsgId)();
}
/* rename max_fname to new_fname */
strcpy(pname, max_fname);
if (rename(seqpath, new_fname) == 0) {
free(seqpath);
free(new_fname);
return seq;
}
if (errno == ENOENT || errno == EEXIST ||
((errno == EPERM || errno == EACCES) && try < 16))
continue;
free(seqpath);
free(new_fname);
GenMsgIdErr("can't rename .seq file");
return (*altGenMsgId)();
}
}
dword GenMsgId(char *seqdir, unsigned long max_outrun)
{
return GenMsgIdEx(seqdir, max_outrun, NULL, NULL);
}