主要是userno的重新整理和好友上站通知以及好友名单。
/*-------------------------------------------------------*/
/* util/userno-sync.c */
/*-------------------------------------------------------*/
/* author : hightman.bbs@bbs.dot66.net */
/* target : 自动重整 userno 重复的程式 */
/* create : 2001/12/08 */
/* update : */
/*-------------------------------------------------------*/
/* syntax : userno-sync */
/* NOTICE : 转换部分[好友名单,热讯纪录] */
/* [好友上站通知] [群组记录] */
/*-------------------------------------------------------*/
/* Xfile: friend, bmw, frienz, benz, grp/ */
/*-------------------------------------------------------*/
#include "bbs.h"
#undef FAKE_IO
#define HAVE_GROUP_FUNC
typedef struct
{
char userid[IDLEN+1];
} MAP;
MAP map[70000]; /* 假设最大userno < 70000 */
int total;
/* 以下抄自 group.c */
#ifdef HAVE_GROUP_FUNC
typedef struct
{
char xname_id[IDLEN + 1];
char title_tel[16];
usint gmode;
char date_zip[9];
int unum;
char email[60];
char address[60];
char other[64];
} GRP;
#define GRP_USER 0x01 /* 个人*/
#define GRP_FRIEND 0x02 /* 朋友组 */
#define GRP_BOARD 0x04 /* 看板组 */
#define FN_GRP ".GRP"
#endif
static int
finduserno(userid)
char *userid;
{
int i;
for(i=1; i < total; i++)
{
if(!strcmp(map[i].userid, userid))
return i;
}
return 0;
}
/* save the bmw log */
void
bmw_sync(userid, userno)
char *userid;
int userno;
{
int fd;
char fpath[128];
usr_fpath(fpath, userid, FN_BMW);
fd = f_open(fpath);
if (fd >= 0)
{
FILE *fout;
char folder[80],buf[128];
HDR fhdr;
usr_fpath(folder, userid, ".DIR");
#ifndef FAKE_IO
if (fout = fdopen(hdr_stamp(folder, 0, &fhdr, buf), "w"))
{
BMW bmw;
while (read(fd, &bmw, sizeof(BMW)) == sizeof(BMW))
{
struct tm *ptime = localtime(&bmw.btime);
fprintf(fout, "%s%s(%02d:%02d):%s\033[m\n",
bmw.sender == userno ? "☆" : "\033[32m★",
bmw.userid, ptime->tm_hour, ptime->tm_min, bmw.msg);
}
fclose(fout);
}
close(fd);
fhdr.xmode = MAIL_READ | MAIL_NOREPLY;
strcpy(fhdr.title, "[备 忘 录] 热讯纪录");
strcpy(fhdr.owner, userid);
rec_add(folder, &fhdr, sizeof(fhdr));
unlink(fpath);
#endif
}
}
/* reper, read the data and put it to map */
static void
reaper(userid)
char *userid;
{
int fd;
char buf[256];
ACCT acct;
usr_fpath(buf, userid, FN_ACCT);
fd = open(buf, O_RDWR, 0);
if (fd < 0)
{
printf("Warn: Can't not open [%s], Skip User: %s\n", buf, userid);
return;
}
if(read(fd, &acct, sizeof(acct)) != sizeof(acct))
{
printf("Warn: Invalid acct:%s Skip it!\n", userid);
close(fd);
return;
}
/* 把现有的bmw log 寄回信箱,以免乱掉 */
bmw_sync(acct.userid, acct.userno);
/* 新的userno */
acct.userno = total;
str_ncpy(map[total++].userid, acct.userid, IDLEN);
#ifndef FAKE_IO
lseek(fd, 0, SEEK_SET);
write(fd, &acct, sizeof(ACCT));
ftruncate(fd, sizeof(ACCT));
#endif
printf("%-14s: [%d]\n",acct.userid, acct.userno);
close(fd);
#ifndef FAKE_IO
/* 把现有的frienz删除,等pal_sync时添回 */
#ifdef HAVE_ALOHA
usr_fpath(buf, userid, FN_FRIEND_BENZ);
unlink(buf);
#endif
#endif
}
/* traverse */
static void
traverse(fpath)
char *fpath;
{
DIR *dirp;
struct dirent *de;
char *fname;
if (!(dirp = opendir(fpath)))
{
printf("Warn: can't now open [%s]\n", fpath);
return;
}
while (de = readdir(dirp))
{
fname = de->d_name;
if (fname[0] > ' ' && fname[0] != '.')
reaper(fname);
}
closedir(dirp);
}
/* pal sync */
void
pal_sync2(fpath, userid, myuno)
char *fpath;
char *userid;
int myuno;
{
int fd, size = 0;
struct stat st;
if ((fd = open(fpath, O_RDWR, 0600)) < 0)
{
printf("Warn: Can't open [%s]!\n", fpath);
return;
}
if (!fstat(fd, &st) && (size = st.st_size) > 0)
{
PAL *pbase, *phead, *ptail;
int userno, num;
pbase = phead = (PAL *) malloc(size);
size = read(fd, pbase, size);
num = 0;
if (size >= sizeof(PAL))
{
ptail = (PAL *) ((char *) pbase + size);
while (phead < ptail)
{
if (userno = finduserno(phead->userid))
{
phead->userno = userno;
#ifdef HAVE_ALOHA
if((fpath[0] == 'u') && (userno != myuno) && !(phead->ftype & PAL_BAD
))
{
char folder[64];
BMW bmw;
memset(&bmw, 0, sizeof(BMW));
bmw.recver = myuno;
str_ncpy(bmw.userid, userid, IDLEN);
usr_fpath(folder, phead->userid, FN_FRIEND_BENZ);
rec_add(folder, &bmw, sizeof(BMW));
}
#endif
phead++;
num++;
continue;
}
ptail--;
if (phead >= ptail)
break;
memcpy(phead, ptail, sizeof(PAL));
}
size = (char *) ptail - (char *) pbase;
if (num > 0)
{
if (num > 1)
xsort(pbase, num, sizeof(PAL), str_cmp);
#ifndef FAKE_IO
size = sizeof(PAL) * num;
lseek(fd, 0, SEEK_SET);
write(fd, pbase, size);
ftruncate(fd, size);
#endif
printf("PATH : %s PAL : %d\n",fpath,size/sizeof(PAL));
}
}
free(pbase);
}
close(fd);
#ifndef FAKE_IO
if (size <= 0)
unlink(fpath);
#endif
}
#ifdef HAVE_GROUP_FUNC
static int
grp_cmp(i, j)
GRP *i, *j;
{
return str_cmp(i->xname_id, j->xname_id);
}
static void
grp_sync(userid)
char *userid;
{
char fpath[80];
int fd;
usr_fpath(fpath, userid, FN_GRP);
if ((fd = open(fpath, O_RDONLY)) >= 0)
{
GRP grp;
while(read(fd, &grp, sizeof(GRP)) == sizeof(GRP))
{
if(grp.gmode & GRP_FRIEND)
{
char folder[80], tmpbuf[16];
int fd2;
sprintf(tmpbuf, "grp/%s", grp.xname_id);
usr_fpath(folder, userid, tmpbuf);
if((fd2 = open(folder, O_RDWR, 0600)) >= 0)
{
struct stat st;
GRP *xgrp, *ygrp;
int count, size;
fstat(fd2, &st);
size = st.st_size;
if(xgrp = (GRP *) malloc(size))
{
count = read(fd2, xgrp, size) / sizeof(GRP);
if (count > 0)
{
int c = count;
ygrp = xgrp;
do
{
ygrp->unum = finduserno(ygrp->xname_id);
ygrp++;
} while (--c);
if (count > 1) xsort(xgrp, count, sizeof(GRP), grp_cmp);
/* save it */
lseek(fd2, 0, SEEK_SET);
write(fd2, xgrp, size);
ftruncate(fd2, size);
}
free(xgrp);
}
close(fd2);
}
else
printf("Warn: Cant open [%s]\n", folder);
}
}
close(fd);
}
else
printf("Warn: Cant open [%s]\n", fpath);
}
#endif
/* user sync */
static void
user_sync(userid, userno)
char *userid;
{
char buf[256];
usr_fpath(buf, userid, FN_PAL);
pal_sync2(buf, userid, userno);
#ifdef HAVE_GROUP_FUNC
grp_sync(userid);
#endif
#ifndef FAKE_IO /* system logfity */
usr_fpath(buf, userid, FN_BENZ);
unlink(buf);
#endif
}
/* board sync */
static int
int_cmp(a, b)
int *a;
int *b;
{
return *a - *b;
}
static void
bimage(brd)
char *brd;
{
int fd;
char fpath[128];
brd_fpath(fpath, brd, "friend");
if ((fd = open(fpath, O_RDONLY)) >= 0)
{
struct stat st;
PAL *pal, *up;
int count;
fstat(fd, &st);
if (pal = (PAL *) malloc(count = st.st_size))
{
count = read(fd, pal, count) / sizeof(PAL);
if (count > 0)
{
int *userno;
int c = count;
userno = (int *) up = pal;
do
{
*userno++ = up->userno; /* (up->ftype == PAL_BAD) ? -(up->userno) : u
p->userno; */
up++;
} while (--c);
if (count > 1)
xsort(pal, count, sizeof(int), int_cmp);
brd_fpath(fpath,brd, "fimage");
#ifndef FAKE_IO
if ((count = open(fpath, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0)
{
write(count, pal, (char *) userno - (char *) pal);
close(count);
}
#endif
printf("BRD : %s OK~\n",brd);
}
else
{
#ifndef FAKE_IO
brd_fpath(fpath, brd, "fimage");
unlink(fpath);
#endif
printf("BRD : %s UNLINK~\n",brd);
}
free(pal);
}
close(fd);
}
else
{
#ifndef FAKE_IO
brd_fpath(fpath, brd, "fimage");
unlink(fpath);
#endif
printf("BRD : %s UNLINK~\n",brd);
}
}
void
brd_pal_sync()
{
struct dirent *de;
DIR *dirp;
char buf[128],*ptr;
if (!(dirp = opendir("brd")))
{
printf("Warn: Cant not open [brd]\n");
return;
}
while (de = readdir(dirp))
{
ptr = de->d_name;
if (ptr[0] > ' ' && ptr[0] != '.')
{
sprintf(buf,"brd/%s/friend", ptr);
pal_sync2(buf, NULL, 0);
bimage(ptr);
}
}
closedir(dirp);
}
/* main function */
int
main()
{
int ch, fd;
char *fname, fpath[80];
SCHEMA slot;
setgid(BBSGID);
setuid(BBSUID);
chdir(BBSHOME);
total = 1;
strcpy(fname = fpath, "usr/@");
fname = (char *) strchr(fname, '@');
for (ch = 'a'; ch <= 'z'; ch++)
{
fname[0] = ch;
fname[1] = '\0';
traverse(fpath);
} /* a-z */
for (ch = '0'; ch <= '9'; ch++)
{
fname[0] = ch;
fname[1] = '\0';
traverse(fpath);
} /* 0-9 (no use)*/
printf("Msg: Read data ok, total: %d\n", total - 1);
#ifndef FAKE_IO
fd = open(".USR.new", O_CREAT | O_TRUNC | O_WRONLY, 0600);
if(fd < 0)
{
printf("Error: Can't not write to [.USR.new] !\n");
return -1;
}
for(ch = 1; ch < total; ch++)
{
/* save it to .USR */
memset(&slot, 0, sizeof(SCHEMA));
str_ncpy(slot.userid, map[ch].userid, IDLEN);
time(&slot.uptime);
write(fd, &slot, sizeof(SCHEMA));
/* optimize */
user_sync(map[ch].userid, ch); /* now: ch = userno */
}
close(fd);
#endif
/* board pal sync */
brd_pal_sync();
/* result report */
printf("Total sync user: [%d]\n", total - 1);
return 0;
}
--