summaryrefslogtreecommitdiffstats
path: root/mbbsd/friend.c
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
commitae31e19f92e717919ac8e3db9039eb38d2b89aae (patch)
treec70164d6a1852344f44b04a653ae2815043512af /mbbsd/friend.c
downloadpttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/friend.c')
-rw-r--r--mbbsd/friend.c509
1 files changed, 509 insertions, 0 deletions
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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#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;
+}