/* $Id: friend.c,v 1.2 2002/03/09 10:34:58 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; /* ------------------------------------- */ /* �S�O�W�� */ /* ------------------------------------- */ /* Ptt ��L�S�O�W�檺�ɦW */ static char special_list[] = "list.0"; static char special_des[] = "ldes.0"; /* �S�O�W�檺�W�� */ static unsigned int friend_max[8] = { MAX_FRIEND, MAX_REJECT, MAX_LOGIN_INFO, MAX_POST_INFO, MAX_NAMELIST, MAX_NAMELIST, MAX_NAMELIST, MAX_NAMELIST }; /* ���M�n���a�H�W�泣�O * 2 ���O�@���̦hload��shm�u�128 */ /* Ptt �U�دS�O�W�檺�ɦW */ char *friend_file[8] = { FN_OVERRIDES, FN_REJECT, "alohaed", "postlist", "", FN_CANVOTE, FN_WATER, FN_VISABLE }; /* Ptt �U�دS�O�W�檺�ɭz */ static char *friend_desc[8] = { "�ͽ˴y�z�G", "�c�δc���G", "", "", "�y�z�@�U�G", "�벼�̴y�z�G", "�c�δc���G", "�ݪO�n�ʹy�z" }; /* Ptt �U�دS�O�W�檺����ԭz */ static char *friend_list[8] = { "�n�ͦW��", "�a�H�W��", "�W�u�q��", "�s�峹�q��", "�䥦�S�O�W��", "�p�H�벼�W��", "�ݪO�T�n�W��", "�ݪO�n�ͦW��" }; 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: �ѰO���ɤF... */ 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, "�п�ܲĴX���S�O�W�� (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�ޤJ���@�ӦW��?\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) ��ܨ�L�ݪO���S�O�W��"); 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, "�ק�y�z�G", 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) { /* �s����y 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, NULL); } 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, "(�W��W��:%d�ӤH)", 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)�W�[(D)�R��(E)�ק�(P)�ޤJ(L)�ԲӦC�X" "(K)�R����ӦW��(W)����y(Q)�����H[Q]" : "(A)�W�[ (P)�ޤJ��L�W�� (Q)�����H[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, "����W��N�|�Q�R��,�z�T�w�� (a/N)?", uident, 3, LCECHO); if (*uident == 'a') unlink(fpath); dirty = 1; } else if (*uident == 'w' && count) { if (!getdata(0, 0, "�s����y:", uident, 60, DOECHO)) continue; if (getdata(0, 0, "�T�w��X�s����y? [Y]", line, 4, LCECHO) && *line == 'n') continue; friend_water(uident, type); } else break; } if (dirty) { move(2, 0); outs("��s��Ƥ�..�еy��....."); 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, " �Ь����S�O�W����@��²�u�W��:", 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; }