From ae31e19f92e717919ac8e3db9039eb38d2b89aae Mon Sep 17 00:00:00 2001 From: in2 Date: Thu, 7 Mar 2002 15:13:44 +0000 Subject: Initial revision git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- mbbsd/friend.c | 509 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 mbbsd/friend.c (limited to 'mbbsd/friend.c') diff --git a/mbbsd/friend.c b/mbbsd/friend.c new file mode 100644 index 00000000..3d2167ae --- /dev/null +++ b/mbbsd/friend.c @@ -0,0 +1,509 @@ +/* $Id: friend.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +extern char currboard[]; /* name of currently selected board */ +extern char *fn_overrides; +extern userinfo_t *currutmp; +extern char *fn_reject; +extern int usernum; +extern char *str_space; +extern char *msg_uid; + +/* ------------------------------------- */ +/* 特別名單 */ +/* ------------------------------------- */ + +/* Ptt 其他特別名單的檔名 */ +static char special_list[] = "list.0"; +static char special_des[] = "ldes.0"; + +/* 特別名單的上限 */ +static unsigned int friend_max[8] = { + MAX_FRIEND, + MAX_REJECT, + MAX_LOGIN_INFO, + MAX_POST_INFO, + MAX_NAMELIST, + MAX_NAMELIST, + MAX_NAMELIST, + MAX_NAMELIST +}; +/* 雖然好友跟壞人名單都是 * 2 但是一次最多load到shm只能有128 */ + +/* Ptt 各種特別名單的檔名 */ +char *friend_file[8] = { + FN_OVERRIDES, + FN_REJECT, + "alohaed", + "postlist", + "", + FN_CANVOTE, + FN_WATER, + FN_VISABLE +}; + +/* Ptt 各種特別名單的補述 */ +static char *friend_desc[8] = { + "友誼描述:", + "惡形惡狀:", + "", + "", + "描述一下:", + "投票者描述:", + "惡形惡狀:", + "看板好友描述" +}; + +/* Ptt 各種特別名單的中文敘述 */ +static char *friend_list[8] = { + "好友名單", + "壞人名單", + "上線通知", + "新文章通知", + "其它特別名單", + "私人投票名單", + "看板禁聲名單", + "看板好友名單" +}; + +static void setfriendfile(char *fpath, int type) { + if (type <= 4) /* user list Ptt */ + setuserfile(fpath, friend_file[type]); + else /* board list */ + setbfile(fpath, currboard, friend_file[type]); +} + +static int friend_count(char *fname) { + FILE *fp; + int count = 0; + char buf[200]; + +#if 0 + if ((fp = fopen(fname, "r"))) + while (fgets(buf, 200, fp)) + count++; +#endif + +/*rocker.011018: 忘記關檔了... */ + if ((fp = fopen(fname, "r"))) + { + while (fgets(buf, 200, fp)) count++; + fclose (fp); + } + + return count; +} + +void friend_add(char *uident, int type) { + char fpath[80]; + + setfriendfile(fpath, type); + if (friend_count(fpath) > friend_max[type]) + return; + + if ((uident[0] > ' ') && !belong(fpath, uident)) + { + FILE *fp; + char buf[40] = ""; + char t_uident[IDLEN + 1]; + + /* Thor: avoid uident run away when get data */ + strcpy(t_uident, uident); + + if (type != FRIEND_ALOHA && type != FRIEND_POST) + getdata(2, 0, friend_desc[type], buf, 40, DOECHO); + + if ((fp = fopen(fpath, "a"))) + { + flock(fileno(fp), LOCK_EX); + fprintf(fp, "%-13s%s\n", t_uident, buf); + flock(fileno(fp), LOCK_UN); + fclose(fp); + } + } +} + +static void friend_special() { + char genbuf[70], i, fname[70]; + + friend_file[FRIEND_SPECIAL] = special_list; + for (i = 0; i <= 9; i++) + { + sprintf(genbuf, " (\033[36m%d\033[m) .. ", i); + special_des[5] = i + '0'; + setuserfile(fname, special_des); + if (dashf(fname)) + { + /* no NULL check?? */ + FILE *fp = fopen(fname, "r"); + + fgets(genbuf + 15, 40, fp); + genbuf[47] = 0; + } + move(i + 12, 0); + clrtoeol(); + outs(genbuf); + } + getdata(22, 0, "請選擇第幾號特別名單 (0~9)[0]?", genbuf, 3, LCECHO); + if (genbuf[0] >= '0' && genbuf[0] <= '9') + { + special_list[5] = genbuf[0]; + special_des[5] = genbuf[0]; + } + else + { + special_list[5] = '0'; + special_des[5] = '0'; + } +} + +static void friend_append(int type, int count) { + char fpath[80], i, j, buf[80], sfile[80]; + FILE *fp, *fp1; + + setfriendfile(fpath, type); + + do + { + move(2, 0); + clrtobot(); + outs("要引入哪一個名單?\n"); + for (i = 0, j = 0; i <= 7; i++) + { + if (i == type) + continue; + j++; + if (i <= 4) + sprintf(buf, " (%d) %-s\n", j, friend_list[(int) i]); + else + sprintf(buf, " (%d) %s 版的 %s\n", j, currboard, + friend_list[(int) i]); + outs(buf); + } + outs(" (S) 選擇其他看板的特別名單"); + getdata(11, 0, "請選擇 或 直接[Enter] 放棄:", buf, 3, LCECHO); + if (!buf[0]) + return; + if (buf[0] == 's') + Select(); + } + while (buf[0] < '1' || buf[0] > '9'); + + j = buf[0] - '1'; + if (j >= type) + j++; + if (j == FRIEND_SPECIAL) + friend_special(); + + setfriendfile(sfile, j); + + fp = fopen(sfile, "r"); + while (fgets(buf, 80, fp) && count <= friend_max[type]) + { + char the_id[15]; + + sscanf(buf, "%s", the_id); + if (!belong(fpath, the_id)) + { + if ((fp1 = fopen(fpath, "a"))) + { + flock(fileno(fp1), LOCK_EX); + fputs(buf, fp1); + flock(fileno(fp1), LOCK_UN); + fclose(fp1); + } + } + } + fclose(fp); +} + +void friend_delete(char *uident, int type) { + FILE *fp, *nfp; + char fn[80], fnnew[80]; + char genbuf[200]; + + setfriendfile(fn, type); + + sprintf(fnnew, "%s-", fn); + if ((fp = fopen(fn, "r")) && (nfp = fopen(fnnew, "w"))) + { + int length = strlen(uident); + + while (fgets(genbuf, STRLEN, fp)) + if ((genbuf[0] > ' ') && strncmp(genbuf, uident, length)) + fputs(genbuf, nfp); + fclose(fp); + fclose(nfp); + Rename(fnnew, fn); + } +} + +static void friend_editdesc(char *uident, int type) { + FILE *fp, *nfp; + char fnnew[200], genbuf[200], fn[200]; + setfriendfile(fn, type); + sprintf(fnnew, "%s-", fn); + if ((fp = fopen(fn, "r")) && (nfp = fopen(fnnew, "w"))) + { + int length = strlen(uident); + + while (fgets(genbuf, STRLEN, fp)) + { + if ((genbuf[0] > ' ') && strncmp(genbuf, uident, length)) + fputs(genbuf, nfp); + else if (!strncmp(genbuf, uident, length)) + { + char buf[50] = ""; + getdata(2, 0, "修改描述:", buf, 40, DOECHO); + fprintf(nfp, "%-13s%s\n", uident, buf); + } + } + fclose(fp); + fclose(nfp); + Rename(fnnew, fn); + } +} + +void friend_load() { + FILE *fp; + int myfriends[MAX_FRIEND]; + int myrejects[MAX_REJECT]; + int friendcount, rejectedcount; + char genbuf[200]; + + memset(myfriends, 0, sizeof(myfriends)); + friendcount = 0; + setuserfile(genbuf, fn_overrides); + if ((fp = fopen(genbuf, "r"))) + { + int unum; + + while (fgets(genbuf, STRLEN, fp) && friendcount < MAX_FRIEND - 1) + if (strtok(genbuf, str_space)) + if ((unum = searchuser(genbuf))) + myfriends[friendcount++] = unum; + fclose(fp); + } + memcpy(currutmp->friend, myfriends, sizeof(myfriends)); + + memset(myrejects, 0, sizeof(myrejects)); + rejectedcount = 0; + setuserfile(genbuf, fn_reject); + if ((fp = fopen(genbuf, "r"))) + { + int unum; + + while (fgets(genbuf, STRLEN, fp) && rejectedcount < MAX_REJECT - 1) + if (strtok(genbuf, str_space)) + if ((unum = searchuser(genbuf))) + myrejects[rejectedcount++] = unum; + fclose(fp); + } + memcpy(currutmp->reject, myrejects, sizeof(myrejects)); + if(currutmp->friendtotal) logout_friend_online(); + login_friend_online(); +} + +extern userec_t cuser; + +static void friend_water(char *message, int type) { /* 群體水球 added by Ptt */ + char fpath[80], line[80], userid[IDLEN + 1]; + FILE *fp; + + setfriendfile(fpath, type); + if ((fp = fopen(fpath, "r"))) + while(fgets(line, 80, fp)) { + userinfo_t *uentp; + int tuid; + + sscanf(line, "%s", userid); + if((tuid = searchuser(userid)) && tuid != usernum && + (uentp = (userinfo_t *) search_ulist(tuid)) && + isvisible_uid(tuid)) + my_write(uentp->pid, message, uentp->userid, 1); + } + fclose(fp); +} + +void friend_edit(int type) { + char fpath[80], line[80], uident[20]; + int count, column, dirty; + FILE *fp; + char genbuf[200]; + + if (type == FRIEND_SPECIAL) + friend_special(); + setfriendfile(fpath, type); + + if (type == FRIEND_ALOHA || type == FRIEND_POST) + { + if (dashf(fpath)) + { + sprintf(genbuf, "/bin/cp %s %s.old", fpath, fpath); + system(genbuf); + } + } + + dirty = 0; + while (1) + { + stand_title(friend_list[type]); + move(0, 40); + sprintf(line, "(名單上限:%d個人)", friend_max[type]); + outs(line); + count = 0; + CreateNameList(); + + if ((fp = fopen(fpath, "r"))) + { + move(3, 0); + column = 0; + while (fgets(genbuf, STRLEN, fp)) + { + if (genbuf[0] <= ' ') + continue; + strtok(genbuf, str_space); + AddNameList(genbuf); + prints("%-13s", genbuf); + count++; + if (++column > 5) + { + column = 0; + outc('\n'); + } + } + fclose(fp); + } + getdata(1, 0, (count ? + "(A)增加(D)刪除(E)修改(P)引入(L)詳細列出" + "(K)刪除整個名單(W)丟水球(Q)結束?[Q]" : + "(A)增加 (P)引入其他名單 (Q)結束?[Q]"), + uident, 3, LCECHO); + if (*uident == 'a') + { + move(1, 0); + usercomplete(msg_uid, uident); + if (uident[0] && searchuser(uident) && !InNameList(uident)) + { + friend_add(uident, type); + dirty = 1; + } + } + else if (*uident == 'p') + { + friend_append(type, count); + dirty = 1; + } + else if (*uident == 'e' && count) + { + move(1, 0); + namecomplete(msg_uid, uident); + if (uident[0] && InNameList(uident)) + { + friend_editdesc(uident, type); + } + } + else if (*uident == 'd' && count) + { + move(1, 0); + namecomplete(msg_uid, uident); + if (uident[0] && InNameList(uident)) + { + friend_delete(uident, type); + dirty = 1; + } + } + else if (*uident == 'l' && count) + more(fpath, YEA); + else if (*uident == 'k' && count) + { + getdata(2, 0, "整份名單將會被刪除,您確定嗎 (a/N)?", uident, 3, + LCECHO); + if (*uident == 'a') + unlink(fpath); + dirty = 1; + } + else if (*uident == 'w' && count) + { + if (!getdata(0, 0, "群體水球:", uident, 60, DOECHO)) + continue; + if (getdata(0, 0, "確定丟出群體水球? [Y]", line, 4, LCECHO) && + *line == 'n') + continue; + friend_water(uident, type); + } + else + break; + } + if (dirty) + { + move(2, 0); + outs("更新資料中..請稍候....."); + refresh(); + if (type == FRIEND_ALOHA || type == FRIEND_POST) + { + sprintf(genbuf, "%s.old", fpath); + if ((fp = fopen(genbuf, "r"))) + { + while (fgets(line, 80, fp)) + { + sscanf(line, "%s", uident); + sethomefile(genbuf, uident, + type == FRIEND_ALOHA ? "aloha" : "postnotify"); + del_distinct(genbuf, cuser.userid); + } + fclose(fp); + } + sprintf(genbuf, "%s", fpath); + if ((fp = fopen(genbuf, "r"))) + { + while (fgets(line, 80, fp)) + { + sscanf(line, "%s", uident); + sethomefile(genbuf, uident, + type == FRIEND_ALOHA ? "aloha" : "postnotify"); + add_distinct(genbuf, cuser.userid); + } + fclose(fp); + } + } + else if (type == FRIEND_SPECIAL) + { + genbuf[0] = 0; + setuserfile(line, special_des); + if ((fp = fopen(line, "r"))) + { + fgets(genbuf, 30, fp); + fclose(fp); + } + getdata_buf(2, 0, " 請為此特別名單取一個簡短名稱:", genbuf, 30, + DOECHO); + if ((fp = fopen(line, "w"))) + { + fprintf(fp, "%s", genbuf); + fclose(fp); + } + } + friend_load(); + } +} + +int t_override() { + friend_edit(FRIEND_OVERRIDE); + return 0; +} + +int t_reject() { + friend_edit(FRIEND_REJECT); + return 0; +} -- cgit v1.2.3