summaryrefslogtreecommitdiffstats
path: root/mbbsd/edit.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/edit.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/edit.c')
-rw-r--r--mbbsd/edit.c2256
1 files changed, 2256 insertions, 0 deletions
diff --git a/mbbsd/edit.c b/mbbsd/edit.c
new file mode 100644
index 00000000..19f437af
--- /dev/null
+++ b/mbbsd/edit.c
@@ -0,0 +1,2256 @@
+/* $Id: edit.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/types.h>
+#include "config.h"
+#include "pttstruct.h"
+#include "config.h"
+#include "common.h"
+#include "modes.h"
+#include "perm.h"
+#include "proto.h"
+
+#define WRAPMARGIN (511)
+
+typedef struct textline_t {
+ struct textline_t *prev;
+ struct textline_t *next;
+ int len;
+ char data[WRAPMARGIN + 1];
+} textline_t;
+
+extern int current_font_type;
+extern char *str_author1;
+extern char *str_author2;
+extern int t_lines, t_columns; /* Screen size / width */
+extern int b_lines; /* Screen bottom line number: t_lines-1 */
+extern char quote_file[80];
+extern char quote_user[80];
+extern int curredit;
+extern unsigned int currbrdattr;
+extern char currboard[]; /* name of currently selected board */
+extern char *str_reply;
+extern char *str_post1;
+extern char *str_post2;
+extern char *BBSName;
+extern char fromhost[];
+extern unsigned int currstat;
+extern crosspost_t postrecord;
+extern userinfo_t *currutmp;
+extern int KEY_ESC_arg;
+extern char reset_color[];
+extern char trans_buffer[256];
+
+#define KEEP_EDITING -2
+#define BACKUP_LIMIT 100
+#define SCR_WIDTH 80
+
+enum {
+ NOBODY, MANAGER, SYSOP
+};
+
+static textline_t *firstline = NULL;
+static textline_t *lastline = NULL;
+static textline_t *currline = NULL;
+static textline_t *blockline = NULL;
+static textline_t *top_of_win = NULL;
+static textline_t *deleted_lines = NULL;
+
+extern int local_article;
+extern char real_name[20];
+static char line[WRAPMARGIN + 2];
+static int ifuseanony=0;
+static int currpnt, currln, totaln;
+static int curr_window_line;
+static int redraw_everything;
+static int insert_character;
+static int my_ansimode;
+static int raw_mode;
+static int edit_margin;
+static int blockln = -1;
+static int blockpnt;
+static int prevln = -1;
+static int prevpnt;
+static int line_dirty;
+static int indent_mode;
+static int insert_c = ' ';
+
+static char fp_bak[] = "bak";
+
+char save_title[STRLEN];
+
+/* °O¾ÐÅéºÞ²z»P½s¿è³B²z */
+static void indigestion(i) {
+ fprintf(stderr, "ÄY­«¤º¶Ë %d\n", i);
+}
+
+/* Thor: ansi ®y¼ÐÂà´« for color ½s¿è¼Ò¦¡ */
+static int ansi2n(int ansix, textline_t * line) {
+ register char *data, *tmp;
+ register char ch;
+
+ data = tmp = line->data;
+
+ while(*tmp) {
+ if(*tmp == KEY_ESC) {
+ while((ch = *tmp) && !isalpha(ch))
+ tmp++;
+ if(ch)
+ tmp++;
+ continue;
+ }
+ if(ansix <= 0)
+ break;
+ tmp++;
+ ansix--;
+ }
+ return tmp - data;
+}
+
+static int n2ansi(int nx, textline_t * line) {
+ register int ansix = 0;
+ register char *tmp,*nxp;
+ register char ch;
+
+ tmp = nxp = line->data;
+ nxp += nx;
+
+ while(*tmp) {
+ if(*tmp == KEY_ESC) {
+ while((ch = *tmp) && !isalpha(ch))
+ tmp++;
+ if(ch)
+ tmp++;
+ continue;
+ }
+ if(tmp >= nxp)
+ break;
+ tmp++;
+ ansix++;
+ }
+ return ansix;
+}
+
+/* ¿Ã¹õ³B²z¡G»²§U°T®§¡BÅã¥Ü½s¿è¤º®e */
+static void edit_msg() {
+ static char *edit_mode[2] = {"¨ú¥N", "´¡¤J"};
+ register int n = currpnt;
+
+ if(my_ansimode) /* Thor: §@ ansi ½s¿è */
+ n = n2ansi(n, currline);
+ n++;
+ move(b_lines, 0);
+ clrtoeol();
+ prints("\033[%sm ½s¿è¤å³¹ \033[31;47m (Ctrl-Z)\033[30m»²§U»¡©ú "
+ "\033[31;47m(^G)\033[30m´¡¤J¹Ï¤å®w \033[31m(^X,^Q)"
+ "\033[30mÂ÷¶}ùø%s¢x%c%c%c%cùø %3d:%3d \033[m",
+ "37;44",
+ edit_mode[insert_character],
+ my_ansimode ? 'A' : 'a', indent_mode ? 'I' : 'i',
+ 'P' , raw_mode ? 'R' : 'r',
+ currln + 1, n);
+}
+
+static textline_t *back_line(textline_t *pos, int num) {
+ while(num-- > 0) {
+ register textline_t *item;
+
+ if(pos && (item = pos->prev)) {
+ pos = item;
+ currln--;
+ }
+ }
+ return pos;
+}
+
+static textline_t *forward_line(textline_t *pos, int num) {
+ while(num-- > 0) {
+ register textline_t *item;
+
+ if(pos && (item = pos->next)) {
+ pos = item;
+ currln++;
+ }
+ }
+ return pos;
+}
+
+static int getlineno() {
+ int cnt = 0;
+ textline_t *p = currline;
+
+ while(p && (p != top_of_win)) {
+ cnt++;
+ p = p->prev;
+ }
+ return cnt;
+}
+
+static char *killsp(char *s) {
+ while(*s == ' ')
+ s++;
+ return s;
+}
+
+static textline_t *alloc_line() {
+ register textline_t *p;
+
+ if((p = (textline_t *)malloc(sizeof(textline_t)))) {
+ memset(p, 0, sizeof(textline_t));
+ return p;
+ }
+
+ indigestion(13);
+ abort_bbs(0);
+ return NULL;
+}
+
+/* append p after line in list. keeps up with last line */
+static void append(textline_t *p, textline_t *line) {
+ register textline_t *n;
+
+ if((p->next = n = line->next))
+ n->prev = p;
+ else
+ lastline = p;
+ line->next = p;
+ p->prev = line;
+}
+
+/*
+ delete_line deletes 'line' from the list,
+ and maintains the lastline, and firstline pointers.
+*/
+
+static void delete_line(textline_t *line) {
+ register textline_t *p = line->prev;
+ register textline_t *n = line->next;
+
+ if(!p && !n) {
+ line->data[0] = line->len = 0;
+ return;
+ }
+ if(n)
+ n->prev = p;
+ else
+ lastline = p;
+ if(p)
+ p->next = n;
+ else
+ firstline = n;
+ strcat(line->data, "\n");
+ line->prev = deleted_lines;
+ deleted_lines = line;
+ totaln--;
+}
+
+static int ask(char *prompt) {
+ int ch;
+
+ move (0, 0);
+ clrtoeol ();
+ standout ();
+ prints ("%s", prompt);
+ standend ();
+ ch = igetkey ();
+ move (0, 0);
+ clrtoeol ();
+ return (ch);
+}
+
+static int indent_spcs() {
+ textline_t* p;
+ int spcs;
+
+ if(!indent_mode)
+ return 0;
+
+ for(p = currline; p; p = p->prev) {
+ for(spcs = 0; p->data[spcs] == ' '; ++spcs);
+ if (p->data[spcs])
+ return spcs;
+ }
+ return 0;
+}
+
+/* split 'line' right before the character pos */
+static void split(textline_t *line, int pos) {
+ if(pos <= line->len) {
+ register textline_t *p = alloc_line();
+ register char *ptr;
+ int spcs = indent_spcs();
+
+ totaln++;
+
+ p->len = line->len - pos + spcs;
+ line->len = pos;
+
+ memset(p->data, ' ', spcs);
+ p->data[spcs] = 0;
+ strcat(p->data, (ptr = line->data + pos));
+ ptr[0] = '\0';
+ append(p, line);
+ if(line == currline && pos <= currpnt) {
+ currline = p;
+ if(pos == currpnt)
+ currpnt = spcs;
+ else
+ currpnt -= pos;
+ curr_window_line++;
+ currln++;
+ }
+ redraw_everything = YEA;
+ }
+}
+
+static void insert_char(int ch) {
+ register textline_t *p = currline;
+ register int i = p->len;
+ register char *s;
+ int wordwrap = YEA;
+
+ if(currpnt > i) {
+ indigestion(1);
+ return;
+ }
+ if(currpnt < i && !insert_character) {
+ p->data[currpnt++] = ch;
+ /* Thor: ansi ½s¿è, ¥i¥Hoverwrite, ¤£»\¨ì ansi code */
+ if(my_ansimode)
+ currpnt = ansi2n(n2ansi(currpnt, p),p);
+ } else {
+ while(i >= currpnt) {
+ p->data[i + 1] = p->data[i];
+ i--;
+ }
+ p->data[currpnt++] = ch;
+ i = ++(p->len);
+ }
+ if(i < WRAPMARGIN)
+ return;
+ s = p->data + (i - 1);
+ while(s != p->data && *s == ' ')
+ s--;
+ while(s != p->data && *s != ' ')
+ s--;
+ if(s == p->data) {
+ wordwrap = NA;
+ s = p->data + (i - 2);
+ }
+ split(p, (s - p->data) + 1);
+ p = p->next;
+ i = p->len;
+ if(wordwrap && i >= 1) {
+ if(p->data[i - 1] != ' ') {
+ p->data[i] = ' ';
+ p->data[i + 1] = '\0';
+ p->len++;
+ }
+ }
+}
+
+static void insert_string(char *str) {
+ int ch;
+
+ while((ch = *str++)) {
+ if(isprint2(ch) || ch == '\033')
+ insert_char(ch);
+ else if(ch == '\t') {
+ do {
+ insert_char(' ');
+ } while(currpnt & 0x7);
+ } else if(ch == '\n')
+ split(currline, currpnt);
+ }
+}
+
+static int undelete_line() {
+ textline_t* p = deleted_lines;
+ textline_t* currline0 = currline;
+ textline_t* top_of_win0 = top_of_win;
+ int currpnt0 = currpnt;
+ int currln0 = currln;
+ int curr_window_line0 = curr_window_line;
+ int indent_mode0 = indent_mode;
+
+ if(!deleted_lines)
+ return 0;
+
+ indent_mode = 0;
+ insert_string(deleted_lines->data);
+ indent_mode = indent_mode0;
+ deleted_lines = deleted_lines->prev;
+ free(p);
+
+ currline = currline0;
+ top_of_win = top_of_win0;
+ currpnt = currpnt0;
+ currln = currln0;
+ curr_window_line = curr_window_line0;
+ return 0;
+}
+
+/*
+ 1) lines were joined and one was deleted
+ 2) lines could not be joined
+ 3) next line is empty
+ returns false if:
+ 1) Some of the joined line wrapped
+*/
+static int join(textline_t *line) {
+ register textline_t *n;
+ register int ovfl;
+
+ if(!(n = line->next))
+ return YEA;
+ if(!*killsp(n->data))
+ return YEA;
+
+ ovfl = line->len + n->len - WRAPMARGIN;
+ if(ovfl < 0) {
+ strcat(line->data, n->data);
+ line->len += n->len;
+ delete_line(n);
+ return YEA;
+ } else {
+ register char *s;
+
+ s = n->data + n->len - ovfl - 1;
+ while(s != n->data && *s == ' ')
+ s--;
+ while(s != n->data && *s != ' ')
+ s--;
+ if(s == n->data)
+ return YEA;
+ split(n, (s - n->data) + 1);
+ if(line->len + n->len >= WRAPMARGIN) {
+ indigestion(0);
+ return YEA;
+ }
+ join(line);
+ n = line->next;
+ ovfl = n->len - 1;
+ if(ovfl >= 0 && ovfl < WRAPMARGIN - 2) {
+ s = &(n->data[ovfl]);
+ if(*s != ' ') {
+ strcpy(s, " ");
+ n->len++;
+ }
+ }
+ return NA;
+ }
+}
+
+static void delete_char() {
+ register int len;
+
+ if((len = currline->len)) {
+ register int i;
+ register char *s;
+
+ if(currpnt >= len) {
+ indigestion(1);
+ return;
+ }
+ for(i = currpnt, s = currline->data + i; i != len; i++, s++)
+ s[0] = s[1];
+ currline->len--;
+ }
+}
+
+static void load_file(FILE *fp) {
+ int indent_mode0 = indent_mode;
+
+ indent_mode = 0;
+ while(fgets(line, WRAPMARGIN + 2, fp))
+ insert_string(line);
+ fclose(fp);
+ indent_mode = indent_mode0;
+}
+
+/* ¼È¦sÀÉ */
+char *ask_tmpbuf(int y) {
+ static char fp_buf[10] = "buf.0";
+ static char msg[] = "½Ð¿ï¾Ü¼È¦sÀÉ (0-9)[0]: ";
+
+ msg[19] = fp_buf[4];
+ do {
+ if(!getdata(y, 0, msg, fp_buf + 4, 4, DOECHO))
+ fp_buf[4] = msg[19];
+ } while(fp_buf[4] < '0' || fp_buf[4] > '9');
+ return fp_buf;
+}
+
+static void read_tmpbuf(int n) {
+ FILE *fp;
+ char fp_tmpbuf[80];
+ char tmpfname[] = "buf.0";
+ char *tmpf;
+ char ans[4] = "y";
+
+ if(0 <= n && n <= 9) {
+ tmpfname[4] = '0' + n;
+ tmpf = tmpfname;
+ } else {
+ tmpf = ask_tmpbuf(3);
+ n = tmpf[4] - '0';
+ }
+
+ setuserfile(fp_tmpbuf, tmpf);
+ if(n != 0 && n != 5 && more(fp_tmpbuf, NA) != -1)
+ getdata(b_lines - 1, 0, "½T©wŪ¤J¶Ü(Y/N)?[Y]", ans, 4, LCECHO);
+ if(*ans != 'n' && (fp = fopen(fp_tmpbuf, "r"))) {
+ prevln = currln;
+ prevpnt = currpnt;
+ load_file(fp);
+ while(curr_window_line >= b_lines) {
+ curr_window_line--;
+ top_of_win = top_of_win->next;
+ }
+ }
+}
+
+static void write_tmpbuf() {
+ FILE *fp;
+ char fp_tmpbuf[80], ans[4];
+ textline_t *p;
+
+ setuserfile(fp_tmpbuf, ask_tmpbuf(3));
+ if(dashf(fp_tmpbuf)) {
+ more(fp_tmpbuf, NA);
+ getdata(b_lines - 1, 0, "¼È¦sÀɤw¦³¸ê®Æ (A)ªþ¥[ (W)Âмg (Q)¨ú®ø¡H[A] ",
+ ans, 4, LCECHO);
+
+ if(ans[0] == 'q')
+ return;
+ }
+
+ if((fp = fopen(fp_tmpbuf, (ans[0] == 'w' ? "w" : "a+")))) {
+ for(p = firstline; p; p = p->next) {
+ if(p->next || p->data[0])
+ fprintf(fp, "%s\n", p->data);
+ }
+ fclose(fp);
+ }
+}
+
+static void erase_tmpbuf() {
+ char fp_tmpbuf[80];
+ char ans[4] = "n";
+
+ setuserfile(fp_tmpbuf, ask_tmpbuf(3));
+ if(more(fp_tmpbuf, NA) != -1)
+ getdata(b_lines - 1, 0, "½T©w§R°£¶Ü(Y/N)?[N]", ans, 4, LCECHO);
+ if(*ans == 'y')
+ unlink(fp_tmpbuf);
+}
+
+/* ½s¿è¾¹¦Û°Ê³Æ¥÷ */
+void auto_backup() {
+ if(currline) {
+ FILE *fp;
+ textline_t *p, *v;
+ char bakfile[64];
+ int count = 0;
+
+ setuserfile(bakfile, fp_bak);
+ if((fp = fopen(bakfile, "w"))) {
+ for(p = firstline; p != NULL && count < 512; p = v,count++) {
+ v = p->next;
+ fprintf(fp, "%s\n", p->data);
+ free(p);
+ }
+ fclose(fp);
+ }
+ currline = NULL;
+ }
+}
+
+void restore_backup() {
+ char bakfile[80], buf[80];
+
+ setuserfile(bakfile, fp_bak);
+ if(dashf(bakfile)) {
+ stand_title("½s¿è¾¹¦Û°Ê´_­ì");
+ getdata(1, 0, "±z¦³¤@½g¤å³¹©|¥¼§¹¦¨¡A(S)¼g¤J¼È¦sÀÉ (Q)ºâ¤F¡H[S] ",
+ buf, 4, LCECHO);
+ if(buf[0] != 'q') {
+ setuserfile(buf, ask_tmpbuf(3));
+ Rename(bakfile, buf);
+ } else
+ unlink(bakfile);
+ }
+}
+
+/* ¤Þ¥Î¤å³¹ */
+static int garbage_line(char *str) {
+ int qlevel = 0;
+
+ while(*str == ':' || *str == '>') {
+ if(*(++str) == ' ')
+ str++;
+ if(qlevel++ >= 1)
+ return 1;
+ }
+ while(*str == ' ' || *str == '\t')
+ str++;
+ if(qlevel >= 1) {
+ if(!strncmp(str, "¡° ", 3) || !strncmp(str, "==>", 3) ||
+ strstr(str, ") ´£¨ì:\n"))
+ return 1;
+ }
+ return (*str == '\n');
+}
+
+static void do_quote() {
+ int op;
+ char buf[256];
+
+ getdata(b_lines - 1, 0, "½Ð°Ý­n¤Þ¥Î­ì¤å¶Ü(Y/N/All/Repost)¡H[Y] ",
+ buf, 3, LCECHO);
+ op = buf[0];
+
+ if(op != 'n') {
+ FILE *inf;
+
+ if((inf = fopen(quote_file, "r"))) {
+ char *ptr;
+ int indent_mode0 = indent_mode;
+
+ fgets(buf, 256, inf);
+ if((ptr = strrchr(buf, ')')))
+ ptr[1] = '\0';
+ else if((ptr = strrchr(buf, '\n')))
+ ptr[0] = '\0';
+
+ if((ptr = strchr(buf, ':'))) {
+ char *str;
+
+ while(*(++ptr) == ' ');
+
+ /* ¶¶¤â²o¦Ï¡A¨ú±o author's address */
+ if((curredit & EDIT_BOTH) && (str = strchr(quote_user, '.'))) {
+ strcpy(++str, ptr);
+ str = strchr(str, ' ');
+ str[0] = '\0';
+ }
+ } else
+ ptr = quote_user;
+
+ indent_mode = 0;
+ insert_string("¡° ¤Þ­z¡m");
+ insert_string(ptr);
+ insert_string("¡n¤§»Ê¨¥¡G\n");
+
+ if(op != 'a') /* ¥h±¼ header */
+ while(fgets(buf, 256, inf) && buf[0] != '\n');
+
+ if(op == 'a')
+ while(fgets(buf, 256, inf)) {
+ insert_char(':');
+ insert_char(' ');
+ insert_string(Ptt_prints(buf,STRIP_ALL));
+ }
+ else if(op == 'r')
+ while(fgets(buf, 256, inf))
+ insert_string(Ptt_prints(buf,NO_RELOAD));
+ else {
+ if(curredit & EDIT_LIST) /* ¥h±¼ mail list ¤§ header */
+ while (fgets(buf, 256, inf) && (!strncmp(buf, "¡° ", 3)));
+ while(fgets(buf, 256, inf)) {
+ if(!strcmp(buf, "--\n"))
+ break;
+ if(!garbage_line(buf)) {
+ insert_char(':');
+ insert_char(' ');
+ insert_string(Ptt_prints(buf,STRIP_ALL));
+ }
+ }
+ }
+ indent_mode = indent_mode0;
+ fclose(inf);
+ }
+ }
+}
+
+/* ¼f¬d user ¤Þ¨¥ªº¨Ï¥Î */
+static int check_quote() {
+ register textline_t *p = firstline;
+ register char *str;
+ int post_line;
+ int included_line;
+
+ post_line = included_line = 0;
+ while(p) {
+ if(!strcmp(str = p->data, "--"))
+ break;
+ if(str[1] == ' ' && ((str[0] == ':') || (str[0] == '>')))
+ included_line++;
+ else {
+ while(*str == ' ' || *str == '\t')
+ str++;
+ if(*str)
+ post_line++;
+ }
+ p = p->next;
+ }
+
+ if((included_line >> 2) > post_line) {
+ move(4, 0);
+ outs("¥»½g¤å³¹ªº¤Þ¨¥¤ñ¨Ò¶W¹L 80%¡A½Ð±z°µ¨Ç·Lªº­×¥¿¡G\n\n"
+ "\033[1;33m1) ¼W¥[¤@¨Ç¤å³¹ ©Î 2) §R°£¤£¥²­n¤§¤Þ¨¥\033[m");
+ {
+ char ans[4];
+
+ getdata(12, 12, "(E)Ä~Äò½s¿è (W)±j¨î¼g¤J¡H[E] ", ans, 4, LCECHO);
+ if(ans[0] == 'w')
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/* Àɮ׳B²z¡GŪÀÉ¡B¦sÀÉ¡B¼ÐÃD¡Bñ¦WÀÉ */
+static void read_file(char *fpath) {
+ FILE *fp;
+
+ if((fp = fopen(fpath, "r")) == NULL) {
+ if((fp = fopen(fpath, "w+"))) {
+ fclose(fp);
+ return;
+ }
+ indigestion(4);
+ abort_bbs(0);
+ }
+ load_file(fp);
+}
+
+extern userec_t cuser;
+
+void write_header(FILE *fp) {
+ time_t now = time(0);
+
+ if(curredit & EDIT_MAIL || curredit & EDIT_LIST) {
+ fprintf(fp, "%s %s (%s)\n", str_author1, cuser.userid,
+#if defined(REALINFO) && defined(MAIL_REALNAMES)
+ cuser.realname
+#else
+ cuser.username
+#endif
+ );
+ } else {
+ char *ptr;
+ struct {
+ char author[IDLEN + 1];
+ char board[IDLEN + 1];
+ char title[66];
+ time_t date; /* last post's date */
+ int number; /* post number */
+ } postlog;
+
+ strcpy(postlog.author, cuser.userid);
+ ifuseanony=0;
+#ifdef HAVE_ANONYMOUS
+ if(currbrdattr& BRD_ANONYMOUS) {
+ int defanony = (currbrdattr & BRD_DEFAULTANONYMOUS);
+ if(defanony)
+ getdata(3, 0, "½Ð¿é¤J§A·Q¥ÎªºID¡A¤]¥iª½±µ«ö[Enter]¡A"
+ "©Î¬O«ö[r]¥Î¯u¦W¡G", real_name, 12, DOECHO);
+ else
+ getdata(3, 0, "½Ð¿é¤J§A·Q¥ÎªºID¡A¤]¥iª½±µ«ö[Enter]¨Ï¥Î­ìID¡G",
+ real_name, 12, DOECHO);
+ if(!real_name[0] && defanony) {
+ strcpy(real_name, "Anonymous");
+ strcpy(postlog.author, real_name);
+ ifuseanony = 1;
+ } else {
+ if(!strcmp("r",real_name) || (!defanony && !real_name[0]))
+ sprintf(postlog.author,"%s",cuser.userid);
+ else {
+ sprintf(postlog.author,"%s.",real_name);
+ ifuseanony=1;
+ }
+ }
+ }
+#endif
+ strcpy(postlog.board, currboard);
+ ptr = save_title;
+ if(!strncmp(ptr, str_reply, 4))
+ ptr += 4;
+ strncpy(postlog.title, ptr, 65);
+ postlog.date = now;
+ postlog.number = 1;
+ append_record(".post", (fileheader_t *)&postlog, sizeof(postlog));
+#ifdef HAVE_ANONYMOUS
+ if(currbrdattr & BRD_ANONYMOUS) {
+ int defanony = (currbrdattr & BRD_DEFAULTANONYMOUS);
+
+ fprintf(fp, "%s %s (%s) %s %s\n", str_author1, postlog.author ,
+ (((!strcmp(real_name,"r") && defanony) ||
+ (!real_name[0] && (!defanony))) ? cuser.username :
+ "²q²q§Ú¬O½Ö ? ^o^"),
+ local_article ? str_post2 : str_post1, currboard);
+ } else {
+ fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid,
+#if defined(REALINFO) && defined(POSTS_REALNAMES)
+ cuser.realname,
+#else
+ cuser.username,
+#endif
+ local_article ? str_post2 : str_post1, currboard);
+ }
+#else /* HAVE_ANONYMOUS */
+ fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid,
+#if defined(REALINFO) && defined(POSTS_REALNAMES)
+ cuser.realname,
+#else
+ cuser.username,
+#endif
+ local_article ? str_post2 : str_post1, currboard);
+#endif /* HAVE_ANONYMOUS */
+
+ }
+ save_title[72] = '\0';
+ fprintf(fp, "¼ÐÃD: %s\n®É¶¡: %s\n", save_title, ctime(&now));
+}
+
+void addsignature(FILE *fp, int ifuseanony) {
+ FILE *fs;
+ int i;
+ char buf[WRAPMARGIN + 1];
+ char fpath[STRLEN];
+
+ static char msg[] = "½Ð¿ï¾Üñ¦WÀÉ (1-9, 0=¤£¥[)[0]: ";
+ char ch;
+
+ if(!strcmp(cuser.userid,STR_GUEST)) {
+ fprintf(fp, "\n--\n¡° µo«H¯¸ :" BBSNAME "(" MYHOSTNAME
+ ") \n¡» From: %s\n", fromhost);
+ return;
+ }
+ if(!ifuseanony) {
+ i = showsignature(fpath);
+ msg[27] = ch = '0' | (cuser.uflag & SIG_FLAG);
+ getdata(0, 0, msg, buf, 4, DOECHO);
+
+ if(ch != buf[0] && buf[0] >= '0' && buf[0] <= '9') {
+ ch = buf[0];
+ cuser.uflag = (cuser.uflag & ~SIG_FLAG) | (ch & SIG_FLAG);
+ }
+
+ if(ch != '0') {
+ fpath[i] = ch;
+ if((fs = fopen(fpath, "r"))) {
+ fputs("\n--\n", fp);
+ for(i = 0; i < MAX_SIGLINES &&
+ fgets(buf, sizeof(buf), fs); i++)
+ fputs(buf, fp);
+ fclose(fs);
+ }
+ }
+ }
+#ifdef HAVE_ORIGIN
+#ifdef HAVE_ANONYMOUS
+ if(ifuseanony)
+ fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME
+ ") \n¡» From: %s\n", "¼Ê¦W¤Ñ¨Ïªº®a");
+ else {
+ char temp[32];
+
+ strncpy(temp, fromhost, 31);
+ temp[32] = '\0';
+ fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME
+ ") \n¡» From: %s\n", temp);
+ }
+#else
+ strncpy (temp,fromhost,15);
+ fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME
+ ") \n¡» From: %s\n", temp);
+#endif
+#endif
+}
+
+static int
+write_file(char *fpath, int saveheader, int *islocal) {
+ time_t now;
+ struct tm *ptime;
+ FILE *fp = NULL;
+ textline_t *p, *v;
+ char ans[TTLEN], *msg;
+ int aborted = 0, line = 0, checksum[3], sum = 0, po = 1;
+
+ stand_title("Àɮ׳B²z");
+ if(currstat == SMAIL)
+ msg = "[S]Àx¦s (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò (R/W/D)Ū¼g§R¼È¦sÀÉ¡H";
+ else if(local_article)
+ msg = "[L]¯¸¤º«H¥ó (S)Àx¦s (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò "
+ "(R/W/D)Ū¼g§R¼È¦sÀÉ¡H";
+ else
+ msg = "[S]Àx¦s (L)¯¸¤º«H¥ó (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò "
+ "(R/W/D)Ū¼g§R¼È¦sÀÉ¡H";
+ getdata(1, 0, msg, ans, 3, LCECHO);
+
+ switch(ans[0]) {
+ case 'a':
+ outs("¤å³¹\033[1m ¨S¦³ \033[m¦s¤J");
+ safe_sleep(1);
+ aborted = -1;
+ break;
+ case 'r':
+ read_tmpbuf(-1);
+ case 'e':
+ return KEEP_EDITING;
+ case 'w':
+ write_tmpbuf();
+ return KEEP_EDITING;
+ case 'd':
+ erase_tmpbuf();
+ return KEEP_EDITING;
+ case 't':
+ move(3, 0);
+ prints("¼ÐÃD¡G%s", save_title);
+ strcpy(ans,save_title);
+ if(getdata_buf(4, 0, "·s¼ÐÃD¡G", ans, TTLEN, DOECHO))
+ strcpy(save_title, ans);
+ return KEEP_EDITING;
+ case 's':
+ if(!HAS_PERM(PERM_LOGINOK)) {
+ local_article = 1;
+ move(2, 0);
+ prints("±z©|¥¼³q¹L¨­¥÷½T»{¡A¥u¯à Local Save¡C\n");
+ pressanykey();
+ } else
+ local_article = 0;
+ break;
+ case 'l':
+ local_article = 1;
+ }
+
+ if(!aborted) {
+ if(saveheader && !(curredit & EDIT_MAIL) && check_quote())
+ return KEEP_EDITING;
+
+ if(!*fpath) {
+ sethomepath(fpath, cuser.userid);
+ strcpy(fpath, tempnam(fpath, "ve_"));
+ }
+
+ if((fp = fopen(fpath, "w")) == NULL) {
+ indigestion(5);
+ abort_bbs(0);
+ }
+ if(saveheader)
+ write_header(fp);
+ }
+
+ for(p = firstline; p; p = v) {
+ v = p->next;
+ if(!aborted) {
+ msg = p->data;
+ if(v || msg[0]) {
+ trim(msg);
+
+ line++;
+ if(currstat == POSTING && po) {
+ saveheader = str_checksum(msg);
+ if(saveheader) {
+ if(postrecord.checksum[po] == saveheader) {
+ po++;
+ if(po > 3) {
+ postrecord.times++;
+ po =0;
+ }
+ } else
+ po = 1;
+ if(currstat == POSTING && line >= totaln/2 &&
+ sum < 3) {
+ checksum[sum++] = saveheader;
+ }
+ }
+ }
+#ifdef SUPPORT_GB
+ if(current_font_type == TYPE_GB)
+ {
+ fprintf(fp, "%s\n", hc_convert_str(msg, HC_GBtoBIG, HC_DO_SINGLE));
+ }
+ else
+#endif
+ fprintf(fp, "%s\n", msg);
+ }
+ }
+ free(p);
+ }
+ currline = NULL;
+
+ if(postrecord.times > MAX_CROSSNUM - 1)
+ anticrosspost();
+
+ if(po && sum == 3) {
+ memcpy(&postrecord.checksum[1], checksum, sizeof(int) * 3);
+ postrecord.times =0;
+ }
+ if(!aborted) {
+ if(islocal)
+ *islocal = (local_article == 1);
+ if(currstat == POSTING || currstat == SMAIL)
+ addsignature(fp,ifuseanony);
+ else if(currstat == REEDIT
+#ifndef ALL_REEDIT_LOG
+ && strcmp(currboard, "SYSOP") == 0
+#endif
+ )
+ {
+ time(&now);
+ ptime = localtime(&now);
+ fprintf(fp,
+ "¡° ½s¿è: %-15s ¨Ó¦Û: %-20s (%02d/%02d %02d:%02d)\n",
+ cuser.userid, fromhost,
+ ptime->tm_mon+1,ptime->tm_mday,ptime->tm_hour,ptime->tm_min);
+ }
+
+ fclose(fp);
+ if(local_article && (currstat == POSTING))
+ return 0;
+ return 0;
+ }
+ return aborted;
+}
+
+
+static void display_buffer() {
+ register textline_t *p;
+ register int i;
+ int inblock;
+ char buf[WRAPMARGIN + 2];
+ int min, max;
+
+ if(currpnt > blockpnt) {
+ min = blockpnt;
+ max = currpnt;
+ } else {
+ min = currpnt;
+ max = blockpnt;
+ }
+
+ for(p = top_of_win, i = 0; i < b_lines; i++) {
+ move(i, 0);
+ clrtoeol();
+ if(blockln >= 0 &&
+ ((blockln <= currln && blockln <= (currln - curr_window_line + i) &&
+ (currln - curr_window_line + i) <= currln) ||
+ (currln <= (currln - curr_window_line + i) &&
+ (currln - curr_window_line + i) <= blockln))) {
+ outs("\033[7m");
+ inblock = 1;
+ } else
+ inblock = 0;
+ if(p) {
+ if(my_ansimode)
+ if(currln == blockln && p == currline && max > min) {
+ outs("\033[m");
+ strncpy(buf, p->data, min);
+ buf[min] = 0;
+ outs(buf);
+ outs("\033[7m");
+ strncpy(buf, p->data + min, max - min);
+ buf[max - min] = 0;
+ outs(buf);
+ outs("\033[m");
+ outs(p->data + max);
+ } else
+ outs(p->data);
+ else if(currln == blockln && p == currline && max > min) {
+ outs("\033[m");
+ strncpy(buf, p->data, min);
+ buf[min] = 0;
+ edit_outs(buf);
+ outs("\033[7m");
+ strncpy(buf, p->data + min, max - min);
+ buf[max - min] = 0;
+ edit_outs(buf);
+ outs("\033[m");
+ edit_outs(p->data + max);
+ } else
+ edit_outs(&p->data[edit_margin]);
+ p = p->next;
+ if(inblock)
+ outs("\033[m");
+ } else
+ outch('~');
+ }
+ edit_msg();
+}
+
+static void goto_line(int lino) {
+ char buf[10];
+
+ if(lino > 0 ||
+ (getdata(b_lines - 1, 0, "¸õ¦Ü²Ä´X¦æ:", buf, 10, DOECHO) &&
+ sscanf(buf, "%d", &lino) && lino > 0)) {
+ textline_t* p;
+
+ prevln = currln;
+ prevpnt = currpnt;
+ p = firstline;
+ currln = lino - 1;
+
+ while(--lino && p->next)
+ p = p->next;
+
+ if(p)
+ currline = p;
+ else {
+ currln = totaln;
+ currline = lastline;
+ }
+ currpnt = 0;
+ if(currln < 11) {
+ top_of_win = firstline;
+ curr_window_line = currln;
+ } else {
+ int i;
+
+ curr_window_line = 11;
+ for(i = curr_window_line; i; i--)
+ p = p->prev;
+ top_of_win = p;
+ }
+ }
+ redraw_everything = YEA;
+}
+
+char *strcasestr(const char* big, const char* little) {
+ char* ans = (char*)big;
+ int len = strlen(little);
+ char* endptr = (char*)big + strlen(big) - len;
+
+ while(ans <= endptr)
+ if(!strncasecmp(ans, little, len))
+ return ans;
+ else
+ ans++;
+ return 0;
+}
+
+/*
+ mode:
+ 0: prompt
+ 1: forward
+ -1: backward
+*/
+static void search_str(int mode) {
+ static char str[80];
+ typedef char* (*FPTR)();
+ static FPTR fptr;
+ char ans[4] = "n";
+
+ if(!mode) {
+ if(getdata_buf(b_lines - 1, 0,"[·j´M]ÃöÁä¦r:",str, 65, DOECHO))
+ if(*str) {
+ if(getdata(b_lines - 1, 0, "°Ï¤À¤j¤p¼g(Y/N/Q)? [N] ",
+ ans, 4, LCECHO) && *ans == 'y')
+ fptr = strstr;
+ else
+ fptr = strcasestr;
+ }
+ }
+
+ if(*str && *ans != 'q') {
+ textline_t* p;
+ char *pos = NULL;
+ int lino;
+
+ if(mode >= 0) {
+ for(lino = currln, p = currline; p; p = p->next, lino++)
+ if((pos = fptr(p->data + (lino == currln ? currpnt + 1 : 0),
+ str)) && (lino != currln ||
+ pos - p->data != currpnt))
+ break;
+ } else {
+ for(lino = currln, p = currline; p; p = p->prev, lino--)
+ if((pos = fptr(p->data, str)) &&
+ (lino != currln || pos - p->data != currpnt))
+ break;
+ }
+ if(pos) {
+ prevln = currln;
+ prevpnt = currpnt;
+ currline = p;
+ currln = lino;
+ currpnt = pos - p->data;
+ if(lino < 11) {
+ top_of_win = firstline;
+ curr_window_line = currln;
+ } else {
+ int i;
+
+ curr_window_line = 11;
+ for(i = curr_window_line; i; i--)
+ p = p->prev;
+ top_of_win = p;
+ }
+ redraw_everything = YEA;
+ }
+ }
+ if(!mode)
+ redraw_everything = YEA;
+}
+
+static void match_paren() {
+ static char parens[] = "()[]{}";
+ int type;
+ int parenum = 0;
+ char *ptype;
+ textline_t* p;
+ int lino;
+ int c, i = 0;
+
+ if(!(ptype = strchr(parens, currline->data[currpnt])))
+ return;
+
+ type = (ptype - parens) / 2;
+ parenum += ((ptype - parens) % 2) ? -1 : 1;
+
+ if(parenum > 0) {
+ for(lino = currln, p = currline; p; p = p->next, lino++) {
+ lino = lino;
+ for(i = (lino == currln) ? currpnt + 1 : 0;
+ i < strlen(p->data); i++)
+ if(p->data[i] == '/' && p->data[++i] == '*') {
+ ++i;
+ while(1) {
+ while(i < strlen(p->data) - 1 &&
+ !(p->data[i] == '*' && p->data[i + 1] == '/'))
+ i++;
+ if(i >= strlen(p->data) - 1 && p->next) {
+ p = p->next;
+ ++lino;
+ i = 0;
+ } else
+ break;
+ }
+ } else if((c = p->data[i]) == '\'' || c == '"') {
+ while(1) {
+ while(i < (int)(strlen(p->data) - 1))
+ if(p->data[++i] == '\\' && i < strlen(p->data) - 2)
+ ++i;
+ else if(p->data[i] == c)
+ goto end_quote;
+ if(i >= strlen(p->data) - 1 && p->next) {
+ p = p->next;
+ ++lino;
+ i = -1;
+ } else
+ break;
+ }
+end_quote:
+ ;
+ } else if((ptype = strchr(parens, p->data[i])) &&
+ (ptype - parens) / 2 == type)
+ if(!(parenum += ((ptype - parens) % 2) ? -1 : 1))
+ goto p_outscan;
+ }
+ } else {
+ for(lino = currln, p = currline; p; p = p->prev, lino--)
+ for(i = (lino == currln) ? currpnt - 1 : strlen(p->data) - 1;
+ i >= 0; i--)
+ if(p->data[i] == '/' && p->data[--i] == '*' && i > 0) {
+ --i;
+ while(1) {
+ while(i > 0 &&
+ !(p->data[i] == '*' && p->data[i - 1] == '/'))
+ i--;
+ if(i <= 0 && p->prev) {
+ p = p->prev;
+ --lino;
+ i = strlen(p->data) - 1;
+ } else
+ break;
+ }
+ } else if((c = p->data[i]) == '\'' || c == '"') {
+ while(1) {
+ while(i > 0)
+ if(i > 1 && p->data[i - 2] == '\\')
+ i -= 2;
+ else if((p->data[--i]) == c)
+ goto begin_quote;
+ if(i <= 0 && p->prev) {
+ p = p->prev;
+ --lino;
+ i = strlen(p->data);
+ } else
+ break;
+ }
+begin_quote:
+ ;
+ } else if((ptype = strchr(parens, p->data[i])) &&
+ (ptype - parens) / 2 == type)
+ if(!(parenum += ((ptype - parens) % 2) ? -1 : 1))
+ goto p_outscan;
+ }
+p_outscan:
+ if(!parenum) {
+ int top = currln - curr_window_line;
+ int bottom = currln - curr_window_line + b_lines - 1;
+
+ currpnt = i;
+ currline = p;
+ curr_window_line += lino - currln;
+ currln = lino;
+
+ if(lino < top || lino > bottom) {
+ if(lino < 11) {
+ top_of_win = firstline;
+ curr_window_line = currln;
+ } else {
+ int i;
+
+ curr_window_line = 11;
+ for(i = curr_window_line; i; i--)
+ p = p->prev;
+ top_of_win = p;
+ }
+ redraw_everything = YEA;
+ }
+ }
+}
+
+static void block_del(int hide) {
+ if(blockln < 0) {
+ blockln = currln;
+ blockpnt = currpnt;
+ blockline = currline;
+ } else {
+ char fp_tmpbuf[80];
+ FILE* fp;
+ textline_t *begin, *end, *p;
+ char tmpfname[10] = "buf.0";
+ char ans[6] = "w+n";
+
+ move(b_lines - 1, 0);
+ clrtoeol();
+ if(hide == 1)
+ tmpfname[4] = 'q';
+ else if(!hide && !getdata(b_lines - 1, 0, "§â°Ï¶ô²¾¦Ü¼È¦sÀÉ "
+ "(0:Cut, 5:Copy, 6-9, q: Cancel)[0] ",
+ tmpfname + 4, 4, LCECHO))
+ tmpfname[4] = '0';
+ if(tmpfname[4] < '0' || tmpfname[4] > '9')
+ tmpfname[4] = 'q';
+ if('1' <= tmpfname[4] && tmpfname[4] <= '9') {
+ setuserfile(fp_tmpbuf, tmpfname);
+ if(tmpfname[4] != '5' && dashf(fp_tmpbuf)) {
+ more(fp_tmpbuf, NA);
+ getdata(b_lines - 1, 0, "¼È¦sÀɤw¦³¸ê®Æ (A)ªþ¥[ (W)Âмg "
+ "(Q)¨ú®ø¡H[W] ", ans, 4, LCECHO);
+ if(*ans == 'q')
+ tmpfname[4] = 'q';
+ else if(*ans != 'a')
+ *ans = 'w';
+ }
+ if(tmpfname[4] != '5') {
+ getdata(b_lines - 1, 0, "§R°£°Ï¶ô(Y/N)?[N] ",
+ ans + 2, 4, LCECHO);
+ if(ans[2] != 'y')
+ ans[2] = 'n';
+ }
+ } else if(hide != 3)
+ ans[2] = 'y';
+
+ tmpfname[5] = ans[1] = ans[3] = 0;
+ if(tmpfname[4] != 'q') {
+ if(currln >= blockln) {
+ begin = blockline;
+ end = currline;
+ if(ans[2] == 'y' && !(begin == end && currpnt != blockpnt)) {
+ curr_window_line -= (currln - blockln);
+ if(curr_window_line < 0) {
+ curr_window_line = 0;
+ if(end->next)
+ (top_of_win = end->next)->prev = begin->prev;
+ else
+ top_of_win = (lastline = begin->prev);
+ }
+ currln -= (currln - blockln);
+ }
+ } else {
+ begin = currline;
+ end = blockline;
+ }
+ if(ans[2] == 'y' && !(begin == end && currpnt != blockpnt)) {
+ if(begin->prev)
+ begin->prev->next = end->next;
+ else if(end->next)
+ top_of_win = firstline = end->next;
+ else {
+ currline = top_of_win = firstline =
+ lastline = alloc_line();
+ currln = curr_window_line = edit_margin = 0;
+ }
+
+ if(end->next)
+ (currline = end->next)->prev = begin->prev;
+ else if(begin->prev) {
+ currline = (lastline = begin->prev);
+ currln--;
+ if(curr_window_line > 0)
+ curr_window_line--;
+ }
+ }
+
+ setuserfile(fp_tmpbuf, tmpfname);
+ if((fp = fopen(fp_tmpbuf, ans))) {
+ if(begin == end && currpnt != blockpnt) {
+ char buf[WRAPMARGIN + 2];
+
+ if(currpnt > blockpnt) {
+ strcpy(buf, begin->data + blockpnt);
+ buf[currpnt - blockpnt] = 0;
+ } else {
+ strcpy(buf, begin->data + currpnt);
+ buf[blockpnt - currpnt] = 0;
+ }
+ fputs(buf, fp);
+ } else {
+ for(p = begin; p != end; p = p->next)
+ fprintf(fp, "%s\n", p->data);
+ fprintf(fp, "%s\n", end->data);
+ }
+ fclose(fp);
+ }
+
+ if(ans[2] == 'y') {
+ if(begin == end && currpnt != blockpnt) {
+ int min, max;
+
+ if(currpnt > blockpnt) {
+ min = blockpnt;
+ max = currpnt;
+ } else {
+ min = currpnt;
+ max = blockpnt;
+ }
+ strcpy(begin->data + min, begin->data + max);
+ begin->len -= max - min;
+ currpnt = min;
+ } else {
+ for(p = begin; p != end; totaln--)
+ free((p = p->next)->prev);
+ free(end);
+ totaln--;
+ currpnt = 0;
+ }
+ }
+ }
+ blockln = -1;
+ redraw_everything = YEA;
+ }
+}
+
+static void block_shift_left() {
+ textline_t *begin, *end, *p;
+
+ if(currln >= blockln) {
+ begin = blockline;
+ end = currline;
+ } else {
+ begin = currline;
+ end = blockline;
+ }
+ p = begin;
+ while(1) {
+ if(p->len) {
+ strcpy(p->data, p->data + 1);
+ --p->len;
+ }
+ if(p == end)
+ break;
+ else
+ p = p->next;
+ }
+ if(currpnt > currline->len)
+ currpnt = currline->len;
+ redraw_everything = YEA;
+}
+
+static void block_shift_right() {
+ textline_t *begin, *end, *p;
+
+ if(currln >= blockln) {
+ begin = blockline;
+ end = currline;
+ } else {
+ begin = currline;
+ end = blockline;
+ }
+ p = begin;
+ while(1) {
+ if(p->len < WRAPMARGIN) {
+ int i = p->len + 1;
+
+ while(i--)
+ p->data[i + 1] = p->data[i];
+ p->data[0] = insert_character ? ' ' : insert_c;
+ ++p->len;
+ }
+ if(p == end)
+ break;
+ else
+ p = p->next;
+ }
+ if(currpnt > currline->len)
+ currpnt = currline->len;
+ redraw_everything = YEA;
+}
+
+static void transform_to_color(char* line) {
+ while(line[0] && line[1])
+ if(line[0] == '*' && line[1] == '[') {
+ line[0] = KEY_ESC;
+ line += 2;
+ } else
+ ++line;
+}
+
+static void block_color() {
+ textline_t *begin, *end, *p;
+
+ if(currln >= blockln) {
+ begin = blockline;
+ end = currline;
+ } else {
+ begin = currline;
+ end = blockline;
+ }
+ p = begin;
+ while(1) {
+ transform_to_color(p->data);
+ if(p == end)
+ break;
+ else
+ p = p->next;
+ }
+ block_del(1);
+}
+
+/* ½s¿è³B²z¡G¥Dµ{¦¡¡BÁä½L³B²z */
+int vedit(char *fpath, int saveheader, int *islocal) {
+ FILE *fp1;
+ char last = 0, buf[200]; /* the last key you press */
+ int ch, foo;
+ int lastindent = -1;
+ int last_margin;
+ int mode0 = currutmp->mode;
+ int destuid0 = currutmp->destuid;
+ unsigned int money=0;
+ unsigned short int interval=0;
+ time_t now=0,th;
+
+ textline_t* firstline0 = firstline;
+ textline_t* lastline0 = lastline;
+ textline_t* currline0 = currline;
+ textline_t* blockline0 = blockline;
+ textline_t* top_of_win0 = top_of_win;
+ int local_article0 = local_article;
+ int currpnt0 = currpnt;
+ int currln0 = currln;
+ int totaln0 = totaln;
+ int curr_window_line0 = curr_window_line;
+ int insert_character0 = insert_character;
+ int my_ansimode0 = my_ansimode;
+ int edit_margin0 = edit_margin;
+ int blockln0 = blockln, count=0, tin=0;
+
+ currutmp->mode = EDITING;
+ currutmp->destuid = currstat;
+ insert_character = redraw_everything = 1;
+ prevln = blockln = -1;
+
+ line_dirty = currpnt = totaln = my_ansimode = 0;
+ currline = top_of_win = firstline = lastline = alloc_line();
+
+ if(*fpath)
+ read_file(fpath);
+
+ if(*quote_file) {
+ do_quote();
+ *quote_file = '\0';
+ if(quote_file[79] == 'L')
+ local_article = 1;
+ }
+
+ currline = firstline;
+ currpnt = currln = curr_window_line = edit_margin = last_margin = 0;
+
+ while(1) {
+ if(redraw_everything || blockln >= 0) {
+ display_buffer();
+ redraw_everything = NA;
+ }
+ if(my_ansimode)
+ ch = n2ansi(currpnt, currline);
+ else
+ ch = currpnt - edit_margin;
+ move(curr_window_line, ch);
+ if(!line_dirty && strcmp(line, currline->data))
+ strcpy(line, currline->data);
+ ch = igetkey();
+ /* jochang debug */
+ if((interval = (unsigned short int)((th = currutmp->lastact) - now))) {
+ now = th;
+ if((char)ch != last) {
+ money++;
+ last = (char)ch;
+ }
+ }
+ if(interval && interval == tin)
+ count++;
+ else
+ {
+ count=0;
+ tin = interval;
+ }
+ /* ³sÄò240­Óinterval¤@¼Ë , ¤À©ú¬O¦bÀÄ°] */
+ if(count >= 240) {
+ sprintf(buf, "\033[1;33;46m%s\033[37m¦b\033[37;45m%s"
+ "\033[37mªO¹HªkÁÈ¿ú , %s\033[m", cuser.userid,
+ currboard,ctime(&now));
+ log_file ("etc/illegal_money",buf);
+ money = 0 ;
+ post_violatelaw(cuser.userid, "Ptt ¨t²Îĵ¹î", "¹HªkÁÈ¿ú", "¦©°£¤£ªk©Ò±o");
+ mail_violatelaw(cuser.userid, "Ptt ¨t²Îĵ¹î", "¹HªkÁÈ¿ú", "¦©°£¤£ªk©Ò±o");
+// demoney(10000);
+// abort_bbs(0);
+ }
+
+ if(raw_mode)
+ switch (ch) {
+ case Ctrl('S'):
+ case Ctrl('Q'):
+ case Ctrl('T'):
+ continue;
+ break;
+ }
+ if(ch < 0x100 && isprint2(ch)) {
+ insert_char(ch);
+ lastindent = -1;
+ line_dirty = 1;
+ } else {
+ if(ch == Ctrl('P') || ch == KEY_UP || ch == KEY_DOWN ||
+ ch == Ctrl('N')) {
+ if(lastindent == -1)
+ lastindent = currpnt;
+ } else
+ lastindent = -1;
+ if(ch == KEY_ESC)
+ switch(KEY_ESC_arg) {
+ case ',':
+ ch = Ctrl(']');
+ break;
+ case '.':
+ ch = Ctrl('T');
+ break;
+ case 'v':
+ ch = KEY_PGUP;
+ break;
+ case 'a':
+ case 'A':
+ ch = Ctrl('V');
+ break;
+ case 'X':
+ ch = Ctrl('X');
+ break;
+ case 'q':
+ ch = Ctrl('Q');
+ break;
+ case 'o':
+ ch = Ctrl('O');
+ break;
+ case '-':
+ ch = Ctrl('_');
+ break;
+ case 's':
+ ch = Ctrl('S');
+ break;
+ }
+
+ switch(ch) {
+ case Ctrl('X'): /* Save and exit */
+ foo = write_file(fpath, saveheader, islocal);
+ if(foo != KEEP_EDITING) {
+ currutmp->mode = mode0;
+ currutmp->destuid = destuid0;
+ firstline = firstline0;
+ lastline = lastline0;
+ currline = currline0;
+ blockline = blockline0;
+ top_of_win = top_of_win0;
+ local_article = local_article0;
+ currpnt = currpnt0;
+ currln = currln0;
+ totaln = totaln0;
+ curr_window_line = curr_window_line0;
+ insert_character = insert_character0;
+ my_ansimode = my_ansimode0;
+ edit_margin = edit_margin0;
+ blockln = blockln0;
+ if(!foo)
+ return money;
+ else
+ return foo;
+ }
+ line_dirty = 1;
+ redraw_everything = YEA;
+ break;
+ case Ctrl('W'):
+ if(blockln >= 0)
+ block_del(2);
+ line_dirty = 1;
+ break;
+ case Ctrl('Q'): /* Quit without saving */
+ ch = ask("µ²§ô¦ý¤£Àx¦s (Y/N)? [N]: ");
+ if(ch == 'y' || ch == 'Y') {
+ currutmp->mode = mode0;
+ currutmp->destuid = destuid0;
+ firstline = firstline0;
+ lastline = lastline0;
+ currline = currline0;
+ blockline = blockline0;
+ top_of_win = top_of_win0;
+ local_article = local_article0;
+ currpnt = currpnt0;
+ currln = currln0;
+ totaln = totaln0;
+ curr_window_line = curr_window_line0;
+ insert_character = insert_character0;
+ my_ansimode = my_ansimode0;
+ edit_margin = edit_margin0;
+ blockln = blockln0;
+ return -1;
+ }
+ line_dirty = 1;
+ redraw_everything = YEA;
+ break;
+ case Ctrl('C'):
+ ch = insert_character;
+ insert_character = redraw_everything = YEA;
+ if(!my_ansimode)
+ insert_string(reset_color);
+ else {
+ char ans[4];
+ move(b_lines - 2, 55);
+ outs("\033[1;33;40mB\033[41mR\033[42mG\033[43mY\033[44mL"
+ "\033[45mP\033[46mC\033[47mW\033[m");
+ if(getdata(b_lines - 1, 0,
+ "½Ð¿é¤J «G«×/«e´º/­I´º[¥¿±`¥Õ¦r¶Â©³][0wb]¡G",
+ ans, 4, LCECHO)) {
+ char t[] = "BRGYLPCW";
+ char color[15];
+ char *tmp, *apos = ans;
+ int fg, bg;
+
+ strcpy(color, "\033[");
+ if(isdigit(*apos)) {
+ sprintf(color, "%s%c", color, *(apos++));
+ if(*apos)
+ sprintf(color, "%s;", color);
+ }
+ if(*apos) {
+ if((tmp = strchr(t, toupper(*(apos++)))))
+ fg = tmp - t + 30;
+ else
+ fg = 37;
+ sprintf(color, "%s%d", color, fg);
+ }
+ if(*apos) {
+ if((tmp = strchr(t, toupper(*(apos++)))))
+ bg = tmp - t + 40;
+ else
+ bg = 40;
+ sprintf(color, "%s;%d", color, bg);
+ }
+ sprintf(color, "%sm", color);
+ insert_string(color);
+ } else
+ insert_string(reset_color);
+ }
+ insert_character = ch;
+ line_dirty = 1;
+ break;
+ case KEY_ESC:
+ line_dirty = 0;
+ switch(KEY_ESC_arg) {
+ case 'U':
+ t_users();
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case 'i':
+ t_idle();
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case 'n':
+ search_str(1);
+ break;
+ case 'p':
+ search_str(-1);
+ break;
+ case 'L':
+ case 'J':
+ goto_line(0);
+ break;
+ case ']':
+ match_paren();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ read_tmpbuf(KEY_ESC_arg - '0');
+ redraw_everything = YEA;
+ break;
+ case 'l': /* block delete */
+ case ' ':
+ block_del(0);
+ line_dirty = 1;
+ break;
+ case 'u':
+ if(blockln >= 0)
+ block_del(1);
+ line_dirty = 1;
+ break;
+ case 'c':
+ if(blockln >= 0)
+ block_del(3);
+ line_dirty = 1;
+ break;
+ case 'y':
+ undelete_line();
+ break;
+ case 'R':
+ raw_mode ^= 1;
+ line_dirty = 1;
+ break;
+ case 'I':
+ indent_mode ^= 1;
+ line_dirty = 1;
+ break;
+ case 'j':
+ if(blockln >= 0)
+ block_shift_left();
+ else if(currline->len) {
+ int currpnt0 = currpnt;
+ currpnt = 0;
+ delete_char();
+ currpnt = (currpnt0 <= currline->len) ? currpnt0 :
+ currpnt0 - 1;
+ if(my_ansimode)
+ currpnt = ansi2n(n2ansi(currpnt, currline),
+ currline);
+ }
+ line_dirty = 1;
+ break;
+ case 'k':
+ if(blockln >= 0)
+ block_shift_right();
+ else {
+ int currpnt0 = currpnt;
+
+ currpnt = 0;
+ insert_char(' ');
+ currpnt = currpnt0;
+ }
+ line_dirty = 1;
+ break;
+ case 'f':
+ while(currpnt < currline->len &&
+ isalnum(currline->data[++currpnt]));
+ while(currpnt < currline->len &&
+ isspace(currline->data[++currpnt]));
+ line_dirty = 1;
+ break;
+ case 'b':
+ while(currpnt && isalnum(currline->data[--currpnt]));
+ while(currpnt && isspace(currline->data[--currpnt]));
+ line_dirty = 1;
+ break;
+ case 'd':
+ while(currpnt < currline->len) {
+ delete_char();
+ if(!isalnum(currline->data[currpnt]))
+ break;
+ }
+ while(currpnt < currline->len) {
+ delete_char();
+ if(!isspace(currline->data[currpnt]))
+ break;
+ }
+ line_dirty = 1;
+ break;
+ default:
+ line_dirty = 1;
+ }
+ break;
+ case Ctrl('_'):
+ if(strcmp(line, currline->data)) {
+ char buf[WRAPMARGIN];
+
+ strcpy(buf, currline->data);
+ strcpy(currline->data, line);
+ strcpy(line, buf);
+ currline->len = strlen(currline->data);
+ currpnt = 0;
+ line_dirty = 1;
+ }
+ break;
+ case Ctrl('S'):
+ search_str(0);
+ break;
+ case Ctrl('U'):
+ insert_char('\033');
+ line_dirty = 1;
+ break;
+ case Ctrl('V'): /* Toggle ANSI color */
+ my_ansimode ^= 1;
+ if(my_ansimode && blockln >= 0)
+ block_color();
+ clear();
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case Ctrl('I'):
+ do {
+ insert_char(' ');
+ } while(currpnt & 0x7);
+ line_dirty = 1;
+ break;
+ case '\r':
+ case '\n':
+ split(currline, currpnt);
+ line_dirty = 0;
+ break;
+ case Ctrl('G'):
+ {
+ unsigned int currstat0 = currstat;
+ setutmpmode(EDITEXP);
+ a_menu("½s¿è»²§U¾¹", "etc/editexp",
+ (HAS_PERM(PERM_SYSOP) ? SYSOP : NOBODY));
+ currstat = currstat0;
+ }
+ if(trans_buffer[0]) {
+ if((fp1 = fopen(trans_buffer, "r"))) {
+ int indent_mode0 = indent_mode;
+
+ indent_mode = 0;
+ prevln = currln;
+ prevpnt = currpnt;
+ while(fgets(line, WRAPMARGIN + 2, fp1)) {
+ if(!strncmp(line,"§@ªÌ:",5) ||
+ !strncmp(line,"¼ÐÃD:",5) ||
+ !strncmp(line,"®É¶¡:",5))
+ continue;
+ insert_string(line);
+ }
+ fclose(fp1);
+ indent_mode = indent_mode0;
+ while(curr_window_line >= b_lines) {
+ curr_window_line--;
+ top_of_win = top_of_win->next;
+ }
+ }
+ }
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case Ctrl('Z'): /* Help */
+ more("etc/ve.hlp",YEA);
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case Ctrl('L'):
+ clear();
+ redraw_everything = YEA;
+ line_dirty = 1;
+ break;
+ case KEY_LEFT:
+ if(currpnt) {
+ if(my_ansimode)
+ currpnt = n2ansi(currpnt, currline);
+ currpnt--;
+ if(my_ansimode)
+ currpnt = ansi2n(currpnt, currline);
+ line_dirty = 1;
+ } else if(currline->prev) {
+ curr_window_line--;
+ currln--;
+ currline = currline->prev;
+ currpnt = currline->len;
+ line_dirty = 0;
+ }
+ break;
+ case KEY_RIGHT:
+ if(currline->len != currpnt) {
+ if(my_ansimode)
+ currpnt = n2ansi(currpnt, currline);
+ currpnt++;
+ if(my_ansimode)
+ currpnt = ansi2n(currpnt, currline);
+ line_dirty = 1;
+ } else if(currline->next) {
+ currpnt = 0;
+ curr_window_line++;
+ currln++;
+ currline = currline->next;
+ line_dirty = 0;
+ }
+ break;
+ case KEY_UP:
+ case Ctrl('P'):
+ if(currline->prev) {
+ if(my_ansimode)
+ ch = n2ansi(currpnt,currline);
+ curr_window_line--;
+ currln--;
+ currline = currline->prev;
+ if(my_ansimode)
+ currpnt = ansi2n(ch , currline);
+ else
+ currpnt = (currline->len > lastindent) ? lastindent :
+ currline->len;
+ line_dirty = 0;
+ }
+ break;
+ case KEY_DOWN:
+ case Ctrl('N'):
+ if(currline->next) {
+ if(my_ansimode)
+ ch = n2ansi(currpnt,currline);
+ currline = currline->next;
+ curr_window_line++;
+ currln++;
+ if(my_ansimode)
+ currpnt = ansi2n(ch , currline);
+ else
+ currpnt = (currline->len > lastindent) ? lastindent :
+ currline->len;
+ line_dirty = 0;
+ }
+ break;
+ case Ctrl('B'):
+ case KEY_PGUP:
+ redraw_everything = currln;
+ top_of_win = back_line(top_of_win, 22);
+ currln = redraw_everything;
+ currline = back_line(currline, 22);
+ curr_window_line = getlineno();
+ if(currpnt > currline->len)
+ currpnt = currline->len;
+ redraw_everything = YEA;
+ line_dirty = 0;
+ break;
+ case KEY_PGDN:
+ case Ctrl('F'):
+ redraw_everything = currln;
+ top_of_win = forward_line(top_of_win, 22);
+ currln = redraw_everything;
+ currline = forward_line(currline, 22);
+ curr_window_line = getlineno();
+ if(currpnt > currline->len)
+ currpnt = currline->len;
+ redraw_everything = YEA;
+ line_dirty = 0;
+ break;
+ case KEY_END:
+ case Ctrl('E'):
+ currpnt = currline->len;
+ line_dirty = 1;
+ break;
+ case Ctrl(']'): /* start of file */
+ prevln = currln;
+ prevpnt = currpnt;
+ currline = top_of_win = firstline;
+ currpnt = currln = curr_window_line = 0;
+ redraw_everything = YEA;
+ line_dirty = 0;
+ break;
+ case Ctrl('T'): /* tail of file */
+ prevln = currln;
+ prevpnt = currpnt;
+ top_of_win = back_line(lastline, 23);
+ currline = lastline;
+ curr_window_line = getlineno();
+ currln = totaln;
+ redraw_everything = YEA;
+ currpnt = 0;
+ line_dirty = 0;
+ break;
+ case KEY_HOME:
+ case Ctrl('A'):
+ currpnt = 0;
+ line_dirty = 1;
+ break;
+ case KEY_INS: /* Toggle insert/overwrite */
+ case Ctrl('O'):
+ if(blockln >= 0 && insert_character) {
+ char ans[4];
+
+ getdata(b_lines - 1, 0,
+ "°Ï¶ô·L½Õ¥k²¾´¡¤J¦r¤¸(¹w³]¬°ªÅ¥Õ¦r¤¸)",
+ ans, 4, LCECHO);
+ insert_c = (*ans) ? *ans : ' ';
+ }
+ insert_character ^= 1;
+ line_dirty = 1;
+ break;
+ case Ctrl('H'):
+ case '\177': /* backspace */
+ line_dirty = 1;
+ if(my_ansimode) {
+ my_ansimode = 0;
+ clear();
+ redraw_everything = YEA;
+ } else {
+ if(currpnt == 0) {
+ textline_t *p;
+
+ if(!currline->prev)
+ break;
+ line_dirty = 0;
+ curr_window_line--;
+ currln--;
+ currline = currline->prev;
+ currpnt = currline->len;
+ redraw_everything = YEA;
+ if(*killsp(currline->next->data) == '\0') {
+ delete_line(currline->next);
+ break;
+ }
+ p = currline;
+ while(!join(p)) {
+ p = p->next;
+ if(p == NULL) {
+ indigestion(2);
+ abort_bbs(0);
+ }
+ }
+ break;
+ }
+ currpnt--;
+ delete_char();
+ }
+ break;
+ case Ctrl('D'):
+ case KEY_DEL: /* delete current character */
+ line_dirty = 1;
+ if(currline->len == currpnt) {
+ textline_t *p = currline;
+
+ while(!join(p)) {
+ p = p->next;
+ if(p == NULL) {
+ indigestion(2);
+ abort_bbs(0);
+ }
+ }
+ line_dirty = 0;
+ redraw_everything = YEA;
+ } else {
+ delete_char();
+ if(my_ansimode)
+ currpnt = ansi2n(n2ansi(currpnt, currline), currline);
+ }
+ break;
+ case Ctrl('Y'): /* delete current line */
+ currline->len = currpnt = 0;
+ case Ctrl('K'): /* delete to end of line */
+ if(currline->len == 0) {
+ textline_t *p = currline->next;
+ if(!p) {
+ p = currline->prev;
+ if(!p)
+ break;
+ if(curr_window_line > 0) {
+ curr_window_line--;
+ currln--;
+ }
+ }
+ if(currline == top_of_win)
+ top_of_win = p;
+ delete_line(currline);
+ currline = p;
+ redraw_everything = YEA;
+ line_dirty = 0;
+ break;
+ }
+ if(currline->len == currpnt) {
+ textline_t *p = currline;
+
+ while(!join(p)) {
+ p = p->next;
+ if(p == NULL) {
+ indigestion(2);
+ abort_bbs(0);
+ }
+ }
+ redraw_everything = YEA;
+ line_dirty = 0;
+ break;
+ }
+ currline->len = currpnt;
+ currline->data[currpnt] = '\0';
+ line_dirty = 1;
+ break;
+ }
+ if(currln < 0)
+ currln = 0;
+ if(curr_window_line < 0) {
+ curr_window_line = 0;
+ if(!top_of_win->prev)
+ indigestion(6);
+ else {
+ top_of_win = top_of_win->prev;
+ rscroll();
+ }
+ }
+ if(curr_window_line == b_lines) {
+ curr_window_line = t_lines - 2;
+ if(!top_of_win->next)
+ indigestion(7);
+ else {
+ top_of_win = top_of_win->next;
+ move(b_lines, 0);
+ clrtoeol();
+ scroll();
+ }
+ }
+ }
+ edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72;
+
+ if(!redraw_everything) {
+ if(edit_margin != last_margin) {
+ last_margin = edit_margin;
+ redraw_everything = YEA;
+ } else {
+ move(curr_window_line, 0);
+ clrtoeol();
+ if(my_ansimode)
+ outs(currline->data);
+ else
+ edit_outs(&currline->data[edit_margin]);
+ edit_msg();
+ }
+ }
+ }
+}