8
|
1 #include <stdio.h>
|
|
2 #include <strings.h>
|
|
3 #include <stdlib.h>
|
|
4 #include <sys/types.h>
|
|
5 #include <sys/socket.h>
|
|
6 #include <netinet/in.h>
|
|
7 #include <netdb.h>
|
|
8 #include <unistd.h>
|
|
9 #include <errno.h>
|
|
10
|
|
11 #include "vim.h"
|
|
12 #include "reditor.h"
|
|
13
|
|
14 /* Global variables of Vim */
|
|
15 #include "globals.h"
|
|
16
|
|
17 /* Wrapper for Vim */
|
|
18 static void e_msg_wrp(char *msg);
|
|
19 static void e_msg2_wrp(char *msg1, char *msg2);
|
|
20 static void puts_msg_wrpt(char *msg);
|
|
21 static void free_wrp(void *p);
|
|
22 static BUFTYPE* make_new_buf_wrp(char *name);
|
|
23 static void free_buf_wrp(BUFTYPE *buf);
|
|
24 static BUFTYPE* find_buf_by_name_wrp(char *name);
|
|
25 static void open_buffer_memline_wrp(BUFTYPE *buf);
|
|
26 static BUFTYPE* get_curbuf_wrp();
|
|
27 static BUFTYPE* set_curbuf_wrp(BUFTYPE *buf);
|
|
28 static char* get_memline_wrp(BUFTYPE *buf, long lnum);
|
|
29 static int append_memline_wrp(long lnum, char *text);
|
|
30 static int delete_memline_wrp(long lnum);
|
|
31 static int replace_memline_wrp(long lnum, char *text);
|
|
32 static void update_screen_now_wrp();
|
|
33 static void update_screen_later_wrp(BUFTYPE *buf);
|
|
34 static long get_bufmaxline_wrp(BUFTYPE* buf);
|
|
35 static char* getstr_input_wrp(char *msg);
|
|
36 static char *get_fullpath_wrp(BUFTYPE *buf);
|
|
37 static char *get_shortname_wrp(BUFTYPE *buf);
|
|
38 /* Wrapper END */
|
|
39
|
|
40
|
|
41 static rep_T* get_rep();
|
|
42
|
|
43 static int del_ignored_cmd(rep_cmdlist *cmdlist);
|
|
44 static int translate(rep_cmdlist *userlist, rep_cmdlist *tokenlist);
|
|
45 static void set_header_to_pkt(rep_cmdlist *cmdlist);
|
|
46 static int rep_get_listened_fd();
|
|
47 static int set_hostnamebysock(int sock, char *hostname, int maxlen);
|
|
48 static int rep_accept();
|
|
49 static int rep_connect(char *host);
|
|
50
|
|
51 static void* rep_alloc(int size);
|
|
52 static void rep_free(void *obj);
|
|
53
|
|
54 static BUFTYPE* get_buf_by_name(char *name);
|
|
55 static Session* init_session(Session *sn);
|
|
56 static Session* make_session(char *name, BUFTYPE *buf);
|
|
57 static void free_session(Session *sn);
|
|
58 static void free_session_list(Session *head);
|
|
59 static void register_session(Session *sn);
|
|
60 static Session* set_cursession(Session *sn);
|
|
61 static Session* find_session_by_buf(BUFTYPE *buf);
|
|
62 static Session* find_session_by_name(char *name);
|
|
63 static int set_session_info(char *dest_sinfo, char *sname, char *hostname, int port);
|
|
64 static char* get_fullpath(Session *session);
|
|
65 static char* get_shortname(Session *session);
|
|
66
|
|
67 static int make_local_slineup(Session *slineup,
|
|
68 char *hostname,
|
|
69 Session *my_sessions);
|
|
70 static int get_slineup_from_sm(char *servername,
|
|
71 Session *slineup,
|
|
72 char *hostname,
|
|
73 Session *my_sessions);
|
|
74 static char* get_sname_by_snum(int snum);
|
|
75 static int writen(int fd, char *textbuf, unsigned int len);
|
|
76
|
|
77 static char* make_packet(unsigned int cmd,
|
|
78 unsigned int sid,
|
|
79 unsigned int eid,
|
|
80 unsigned int seq,
|
|
81 unsigned int lnum,
|
|
82 char *text);
|
|
83 static char* make_open_packet(char *file_name);
|
|
84 static rep_cmd* make_cmd(unsigned int cmd,
|
|
85 unsigned int sid,
|
|
86 unsigned int eid,
|
|
87 unsigned int seq,
|
|
88 unsigned int lnum,
|
|
89 char *text);
|
|
90 static int free_cmd(rep_cmd *cmd);
|
|
91 static int free_cmdlist(rep_cmdlist *cmdlist);
|
|
92 static void add_cmd_to_list(rep_cmdlist *cmdlist, rep_cmd *cmd);
|
|
93 static int add_pkt_to_list(rep_cmdlist *cmdlist, char *pkt);
|
|
94
|
|
95 static void check_line_change(Session *sn, unsigned int lnum);
|
|
96
|
|
97 static unsigned int get_header(char *buf,int offset);
|
|
98 static int set_header(unsigned int num, char *pkt, int offset);
|
|
99
|
|
100 static int rep_exe_cmd(unsigned int cmd,
|
|
101 unsigned int sid,
|
|
102 unsigned int eid,
|
|
103 unsigned int seq,
|
|
104 unsigned int lnum,
|
|
105 unsigned int textsize,
|
|
106 char *text);
|
|
107 static int rep_exe_pkt(char *pkt);
|
|
108 static int rep_exe_pktlist(rep_cmdlist *cmdlist);
|
|
109 static int rep_exe_cmdlist(rep_cmdlist *cmdlist);
|
|
110
|
|
111 static int rep_recv_cmds(int fd, rep_cmdlist *smcmdlist,rep_cmdlist *txtcmdlist);
|
|
112 static int rep_send_cmds(int fd, rep_cmdlist *cmdlist);
|
|
113
|
|
114 static int session_fd_check(Session *sn, fd_set *rfds_p, fd_set *efds_p);
|
|
115 static int session_fd_set(Session *sn, fd_set *rfds_p, fd_set *efds_p, int max_fds);
|
|
116 static int append_newline_sep_text(Session *sn, char *text);
|
|
117
|
|
118 /* g_rep has an all information of Remote Editor */
|
|
119 rep_T g_rep;
|
|
120
|
|
121
|
|
122
|
|
123 /*
|
|
124 * Wrapper for vim
|
|
125 */
|
|
126
|
|
127 /* エラーメッセージ出力 */
|
|
128 static void
|
|
129 e_msg_wrp(msg)
|
|
130 char * msg;
|
|
131 {
|
|
132 EMSG(msg);
|
|
133 }
|
|
134
|
|
135 static void
|
|
136 e_msg2_wrp(msg1, msg2)
|
|
137 char * msg1;
|
|
138 char * msg2;
|
|
139 {
|
|
140 EMSG2(msg1,msg2);
|
|
141 }
|
|
142
|
|
143 /* 通常のメッセージを出力 */
|
|
144 static void
|
|
145 puts_msg_wrp(msg)
|
|
146 char * msg;
|
|
147 {
|
|
148 MSG_PUTS(msg);
|
|
149 }
|
|
150
|
|
151 static void
|
|
152 free_wrp(p)
|
|
153 void *p;
|
|
154 {
|
|
155 vim_free(p);
|
|
156 return;
|
|
157 }
|
|
158
|
|
159
|
|
160 /* 空の新しいバッファを取得 */
|
|
161 static BUFTYPE *
|
|
162 make_new_buf_wrp(name)
|
|
163 char * name;
|
|
164 {
|
|
165 return buflist_new((char_u*)name, NULL, 0, BLN_LISTED);
|
|
166 }
|
|
167
|
|
168 static void
|
|
169 free_buf_wrp(buf)
|
|
170 BUFTYPE *buf;
|
|
171 {
|
|
172 close_buffer(NULL, buf, DOBUF_DEL);
|
|
173 return;
|
|
174 }
|
|
175
|
|
176
|
|
177 /* 名前からバッファへのポインタを取得 */
|
|
178 static BUFTYPE *
|
|
179 find_buf_by_name_wrp(name)
|
|
180 char * name;
|
|
181 {
|
|
182 char *sfname = NULL; // sfname is used name's address
|
|
183 BUFTYPE *buf;
|
|
184 BUFTYPE *orgbuf;
|
|
185
|
|
186 /* make a full file name. name is changed to absolute path.
|
|
187 * name's address is assigned to sfname. */
|
|
188 fname_expand(buf, (char_u**)&name, (char_u**)&sfname);
|
|
189 buf = buflist_findname((char_u*)name);
|
|
190
|
|
191 free_wrp(name);
|
|
192 return buf;
|
|
193 }
|
|
194
|
|
195 static void
|
|
196 open_buffer_memline_wrp(buf)
|
|
197 BUFTYPE *buf;
|
|
198 {
|
|
199 BUFTYPE *oldbuf;
|
|
200 /*
|
|
201 oldbuf = set_curbuf_wrp(buf);
|
|
202 set_curbuf_wrp(oldbuf);
|
|
203 */
|
|
204 oldbuf = curbuf;
|
|
205 curbuf = buf;
|
|
206 open_buffer(FALSE, NULL);
|
|
207 curbuf = oldbuf;
|
|
208 return;
|
|
209 }
|
|
210
|
|
211
|
|
212 /* 現在編集中のバッファへのポインタを取得 */
|
|
213 extern BUFTYPE *curbuf;
|
|
214 static BUFTYPE *
|
|
215 get_curbuf_wrp()
|
|
216 {
|
|
217 return curbuf;
|
|
218 }
|
|
219
|
|
220 /* buf を編集対象にする。
|
|
221 *それまで編集対象だったバッファへのポインタを返す */
|
|
222 static BUFTYPE *
|
|
223 set_curbuf_wrp(buf)
|
|
224 BUFTYPE *buf;
|
|
225 {
|
|
226 BUFTYPE *cb;
|
|
227 if (buf == NULL)
|
|
228 return NULL;
|
|
229
|
|
230 cb = get_curbuf_wrp();
|
|
231 set_curbuf(buf,DOBUF_GOTO);
|
|
232
|
|
233 return cb;
|
|
234 }
|
|
235
|
|
236 /* 指定した行番号の行のテキスト(文字列)のポインタを取得 */
|
|
237 static char *
|
|
238 get_memline_wrp(buf, lnum)
|
|
239 BUFTYPE *buf; // buf is curbuf
|
|
240 long lnum;
|
|
241 {
|
|
242 // return ml_get(lnum);
|
|
243 return (char*)ml_get_buf(buf, lnum, FALSE);
|
|
244 }
|
|
245
|
|
246 /* 編集中のバッファの行の挿入 */
|
|
247 /* "text" does NOT need to be allocated */
|
|
248 static int
|
|
249 append_memline_wrp(lnum, text)
|
|
250 long lnum;
|
|
251 char *text;
|
|
252 {
|
|
253 int r;
|
|
254 int permit;
|
|
255 rep_T *rep;
|
|
256 rep = get_rep();
|
|
257 permit = rep->permit;
|
|
258 rep->permit = FALSE;
|
|
259
|
|
260 r = ml_append(lnum-1, (char_u*)text, strlen(text)+1, FALSE);
|
|
261 appended_lines_mark(lnum-1,1);
|
|
262
|
|
263 rep->permit = permit;
|
|
264 return r;
|
|
265 }
|
|
266
|
|
267 /* 編集中のバッファの行の削除 */
|
|
268 static int
|
|
269 delete_memline_wrp(lnum)
|
|
270 long lnum;
|
|
271 {
|
|
272 int r;
|
|
273 int permit;
|
|
274 rep_T *rep;
|
|
275 rep = get_rep();
|
|
276 permit = rep->permit;
|
|
277 rep->permit = FALSE;
|
|
278
|
|
279 r = ml_delete(lnum, FALSE);
|
|
280 deleted_lines_mark(lnum,1);
|
|
281
|
|
282 rep->permit = permit;
|
|
283 return r;
|
|
284 }
|
|
285
|
|
286 /* 編集中のバッファの行の置換 */
|
|
287 static int
|
|
288 replace_memline_wrp(lnum, text)
|
|
289 long lnum;
|
|
290 char * text;
|
|
291 {
|
|
292 int r;
|
|
293 int permit;
|
|
294 rep_T *rep;
|
|
295 rep = get_rep();
|
|
296 permit = rep->permit;
|
|
297 rep->permit = FALSE;
|
|
298
|
|
299 r = ml_replace(lnum, (char_u*)text, TRUE);
|
|
300
|
|
301 rep->permit = permit;
|
|
302 return r;
|
|
303 }
|
|
304
|
|
305 /* バッファの編集後の後処理 */
|
|
306 static void
|
|
307 update_screen_now_wrp()
|
|
308 {
|
|
309 check_cursor();
|
|
310 update_screen(CLEAR);
|
|
311 return;
|
|
312 }
|
|
313
|
|
314 static void
|
|
315 update_screen_later_wrp(buf)
|
|
316 BUFTYPE *buf;
|
|
317 {
|
|
318 check_cursor();
|
|
319 return redraw_buf_later(buf, CLEAR);
|
|
320 }
|
|
321
|
|
322 /* 編集中のバッファの行数を返す */
|
|
323 static long
|
|
324 get_bufmaxline_wrp(buf)
|
|
325 BUFTYPE *buf;
|
|
326 {
|
|
327 return buf->b_ml.ml_line_count;
|
|
328 }
|
|
329
|
|
330 /* XXX もう使わないので消す予定 */
|
|
331 /* ユーザに文字列を入力させる */
|
|
332 static char *
|
|
333 getstr_input_wrp(msg)
|
|
334 char *msg; // 入力時のメッセージ
|
|
335 {
|
|
336 char *cmdline;
|
|
337
|
|
338 /* 受け取る文字列は使用後 vim_free() する */
|
|
339 // cmdline = (char*)getcmdline_prompt('@', (char_u*)msg, 0);
|
|
340 cmdline = NULL;
|
|
341
|
|
342 return cmdline;
|
|
343 }
|
|
344
|
|
345 /* get full path of buffer */
|
|
346 static char *
|
|
347 get_fullpath_wrp(buf)
|
|
348 BUFTYPE *buf;
|
|
349 {
|
|
350 return (char*)buf->b_ffname;
|
|
351 }
|
|
352
|
|
353 /* get short name of buffer */
|
|
354 static char *
|
|
355 get_shortname_wrp(buf)
|
|
356 BUFTYPE *buf;
|
|
357 {
|
|
358 return (char*)buf->b_sfname;
|
|
359 }
|
|
360
|
|
361 /* Wrapper END */
|
|
362
|
|
363
|
|
364 static void
|
|
365 puts_sys_err()
|
|
366 {
|
|
367 char errmsg[50];
|
|
368
|
|
369 sprintf(errmsg, "rep>> %d:%s", errno, strerror(errno));
|
|
370 e_msg_wrp(errmsg);
|
|
371 return;
|
|
372 }
|
|
373
|
|
374
|
|
375 static rep_T*
|
|
376 get_rep()
|
|
377 {
|
|
378 return(&g_rep);
|
|
379 }
|
|
380
|
|
381 int
|
|
382 rep_permit()
|
|
383 {
|
|
384 return(g_rep.permit);
|
|
385 }
|
|
386
|
|
387 int
|
|
388 rep_session_permit()
|
|
389 {
|
|
390 return(g_rep.permit && g_rep.cursession && g_rep.cursession->permit);
|
|
391 }
|
|
392
|
|
393 void
|
|
394 rep_start_create_cmds()
|
|
395 {
|
|
396 if (g_rep.cursession) {
|
|
397 g_rep.cursession->permit = TRUE;
|
|
398 }
|
|
399 return;
|
|
400 }
|
|
401
|
|
402 void
|
|
403 rep_stop_create_cmds()
|
|
404 {
|
|
405 if (g_rep.cursession) {
|
|
406 g_rep.cursession->permit = FALSE;
|
|
407 }
|
|
408 return;
|
|
409 }
|
|
410
|
|
411
|
|
412 int
|
|
413 rep_init()
|
|
414 {
|
|
415 /*
|
|
416 * g_rep is global variable and it is zero cleared.
|
|
417 */
|
|
418
|
|
419 char def_hostname[] = "localhost";
|
|
420
|
|
421 // 現在編集対象のバッファはセッションに加える?
|
|
422 g_rep.shead = NULL; //make_session();
|
|
423 g_rep.slineup = NULL;
|
|
424
|
|
425 g_rep.cursession = NULL;
|
|
426 g_rep.servername = NULL;
|
|
427 g_rep.waiting_session_name = NULL;
|
|
428
|
|
429 g_rep.smfd = -1;
|
|
430
|
|
431 g_rep.eid = 0;
|
|
432 g_rep.seqno = 0;
|
|
433
|
|
434 g_rep.permit = FALSE;
|
|
435
|
|
436 if (gethostname(g_rep.hostname, sizeof(g_rep.hostname)) < 0) {
|
|
437 strncpy(g_rep.hostname, def_hostname, sizeof(def_hostname)+1);
|
|
438 }
|
|
439
|
|
440 return(TRUE);
|
|
441 }
|
|
442
|
|
443
|
|
444 /*
|
|
445 * cmdlistを辿り、statメンバが REP_IGNORE であるREPコマンドを削除する。
|
|
446 */
|
|
447 static int
|
|
448 del_ignored_cmd(cmdlist)
|
|
449 rep_cmdlist *cmdlist;
|
|
450 {
|
|
451 rep_cmd *curcmd;
|
|
452 rep_cmd *next;
|
|
453
|
|
454 for (;(cmdlist->head) && (cmdlist->head->stat == REP_IGNORE); cmdlist->head=next) {
|
|
455 next = cmdlist->head->next;
|
|
456 free_cmd(cmdlist->head);
|
|
457 }
|
|
458
|
|
459 if (cmdlist->head == NULL) return(TRUE);
|
|
460
|
|
461 for (curcmd=cmdlist->head; curcmd->next;) {
|
|
462 next = curcmd->next->next;
|
|
463 if (curcmd->next->stat == REP_IGNORE) {
|
|
464 free_cmd(curcmd->next);
|
|
465 curcmd->next = next;
|
|
466 cmdlist->num--;
|
|
467 } else {
|
|
468 curcmd = curcmd->next;
|
|
469 }
|
|
470 }
|
|
471 return(TRUE);
|
|
472 }
|
|
473
|
|
474
|
|
475 /***** translate(UserList, ToknList) *****
|
|
476 入力はトークンとユーザ入力からのREPコマンドのリストで、
|
|
477 それらを比較・変換して、二つのREPコマンドリストを生成する。
|
|
478
|
|
479 -------------
|
|
480 UserList ->| | -> UserList'
|
|
481 | translate |
|
|
482 ToknList ->| | -> ToknList'
|
|
483 -------------
|
|
484
|
|
485 Session ID が異なるときは、可換なので、何もしない。
|
|
486
|
|
487 ToknList + UserList' をトークンとして次のリモートエディタに渡し、
|
|
488 ToknList' は自分のバッファに反映させる。
|
|
489
|
|
490 比較時に行番号が重なったときの処理は以下の表。
|
|
491 なるべくテキストが残るようにしている。
|
|
492 x\y は、TOKEN を x, USER を y するという意味。
|
|
493 0 -- なにもしない
|
|
494 +1 -- 行番号を +1
|
|
495 i -- コマンド id を 'i' にする。
|
|
496 X -- コマンドを削除(無視に)する。
|
|
497
|
|
498 USER
|
|
499 | i | r | d
|
|
500 ---|--------------------
|
|
501 T i | 0\+1 | 0\+1 | 0\+1
|
|
502 O ---|--------------------
|
|
503 K r | +1\0 | 0\X | i\X
|
|
504 E ---|--------------------
|
|
505 N d | +1\0 | X\i | X\X
|
|
506
|
|
507 無視にされた(stat に REP_IGNORE が入っている)REPコマンドは、
|
|
508 全ての比較が終了したときにリストから削除される。
|
|
509 */
|
|
510 static int
|
|
511 translate(userlist, tokenlist) /* userのREPコマンドリスト, tokenのREPコマンドリスト */
|
|
512 rep_cmdlist *userlist;
|
|
513 rep_cmdlist *tokenlist;
|
|
514 {
|
|
515 rep_cmd *usercmd;
|
|
516 rep_cmd *tokencmd;
|
|
517 rep_cmd *unext;
|
|
518 rep_cmd *tnext;
|
|
519
|
|
520 rep_cmd *h_pricmd; // high priority command
|
|
521 rep_cmd *l_pricmd; // low priority command
|
|
522
|
|
523 for (usercmd=userlist->head; usercmd; usercmd=unext) {
|
|
524 unext = usercmd->next;
|
|
525
|
|
526 /* 削除される(予定)のREPコマンドの比較は無視 */
|
|
527 if (usercmd->stat == REP_IGNORE) continue;
|
|
528
|
|
529 for (tokencmd=tokenlist->head; tokencmd; tokencmd=tnext) {
|
|
530 tnext=tokencmd->next;
|
|
531
|
|
532 /* 削除される(予定)のREPコマンドの比較は無視 */
|
|
533 if (tokencmd->stat == REP_IGNORE) continue;
|
|
534 /* XXX 消してもいい??*/
|
|
535 if ( tokencmd->cmd != REP_INSERT_CMD &&
|
|
536 tokencmd->cmd != REP_DELETE_LINE_CMD &&
|
|
537 tokencmd->cmd != REP_REPLACE_CMD) {
|
|
538 tokencmd->stat = REP_IGNORE;
|
|
539 continue;
|
|
540 }
|
|
541 if (usercmd->stat == REP_IGNORE) break;
|
|
542 if ( usercmd->cmd != REP_INSERT_CMD &&
|
|
543 usercmd->cmd != REP_DELETE_LINE_CMD &&
|
|
544 usercmd->cmd != REP_REPLACE_CMD) {
|
|
545 usercmd->stat = REP_IGNORE;
|
|
546 break;
|
|
547 }
|
|
548 if (usercmd->sid != tokencmd->sid) {
|
|
549 // session id が違う場合は何しない
|
|
550 continue;
|
|
551 }
|
|
552 if (usercmd->lnum < tokencmd->lnum) { /* UsersLineNumber < TokensLineNumber */
|
|
553 if (usercmd->cmd == REP_INSERT_CMD) {
|
|
554 tokencmd->lnum++;
|
|
555 } else if (usercmd->cmd == REP_DELETE_LINE_CMD) {
|
|
556 tokencmd->lnum--;
|
|
557 }
|
|
558 } else if (usercmd->lnum > tokencmd->lnum) { /* UsersLineNumber > TokensLineNumber */
|
|
559 if (tokencmd->cmd == REP_INSERT_CMD) {
|
|
560 usercmd->lnum++;
|
|
561 } else if (tokencmd->cmd == REP_DELETE_LINE_CMD) {
|
|
562 usercmd->lnum--;
|
|
563 }
|
|
564 } else if (usercmd->lnum == tokencmd->lnum) { /* UsersLineNumber == TokensLineNumber */
|
|
565
|
|
566 #if 0
|
|
567 /*
|
|
568 * 行番号が重なるとREPコマンドの競合が起こるので、
|
|
569 * どちらかが譲らないといけない。
|
|
570 * uid が小さい方を優先(h_pricmdに)し、
|
|
571 * uid が大きい方(l_pricmd)を変更する。
|
|
572 */
|
|
573
|
|
574 if (usercmd->eid < tokencmd->eid) {
|
|
575 h_pricmd = usercmd;
|
|
576 l_pricmd = tokencmd;
|
|
577 } else {
|
|
578 h_pricmd = tokencmd;
|
|
579 l_pricmd = usercmd;
|
|
580 }
|
|
581 #else
|
|
582 /*
|
|
583 無条件に、自分の方が優先
|
|
584 */
|
|
585 h_pricmd = usercmd;
|
|
586 l_pricmd = tokencmd;
|
|
587 #endif
|
|
588
|
|
589 if (h_pricmd->cmd == REP_INSERT_CMD) {
|
|
590 l_pricmd->lnum++;
|
|
591 } else if (h_pricmd->cmd == REP_REPLACE_CMD) {
|
|
592
|
|
593 if (l_pricmd->cmd == REP_INSERT_CMD) {
|
|
594 h_pricmd->lnum++;
|
|
595 } else if (l_pricmd->cmd == REP_REPLACE_CMD) {
|
|
596 /* h_pricmd が優先され,l_pricmd は削除(無視に)する */
|
|
597 l_pricmd->stat = REP_IGNORE;
|
|
598 } else if (l_pricmd->cmd == REP_DELETE_LINE_CMD) {
|
|
599 /*
|
|
600 * l_pricmd 側ではすでにdeleteされているので、
|
|
601 * h_pricmd を REP_REPLACE_CMD -> REP_INSERT_CMD へ変更。
|
|
602 */
|
|
603 h_pricmd->cmd = REP_INSERT_CMD;
|
|
604 l_pricmd->stat = REP_IGNORE;
|
|
605 }
|
|
606
|
|
607 } else if (h_pricmd->cmd == REP_DELETE_LINE_CMD) {
|
|
608
|
|
609 if (l_pricmd->cmd == REP_INSERT_CMD) {
|
|
610 h_pricmd->lnum++;
|
|
611 } else if (l_pricmd->cmd == REP_REPLACE_CMD) {
|
|
612 /*
|
|
613 * h_pricmd 側ではすでにdeleteされているので、
|
|
614 * l_pricmd 側を REP_REPLACE_CMD -> REP_INSERT_CMD へ変更。
|
|
615 */
|
|
616 l_pricmd->cmd = REP_INSERT_CMD;
|
|
617 h_pricmd->stat= REP_IGNORE;
|
|
618 } else if (l_pricmd->cmd == REP_DELETE_LINE_CMD) {
|
|
619 /*
|
|
620 * 相手と削除する行が重なるので、
|
|
621 * 両方のコマンドを無視にする。
|
|
622 * 相手先ではすでにこの行は削除されている。
|
|
623 */
|
|
624 h_pricmd->stat = REP_IGNORE;
|
|
625 l_pricmd->stat = REP_IGNORE;
|
|
626 break;
|
|
627 } else {
|
|
628 }
|
|
629 } else {
|
|
630 }
|
|
631 }
|
|
632 }
|
|
633 }
|
|
634
|
|
635 return(TRUE);
|
|
636 }
|
|
637
|
|
638
|
|
639 static void
|
|
640 set_header_to_pkt(cmdlist)
|
|
641 rep_cmdlist *cmdlist;
|
|
642 {
|
|
643 rep_cmd *curcmd;
|
|
644 for (curcmd=cmdlist->head; curcmd; curcmd=curcmd->next) {
|
|
645 set_header(curcmd->cmd, curcmd->pkt, REP_CMD_OFFSET);
|
|
646 set_header(curcmd->sid, curcmd->pkt, REP_SID_OFFSET);
|
|
647 set_header(curcmd->eid, curcmd->pkt, REP_EID_OFFSET);
|
|
648 set_header(curcmd->seq, curcmd->pkt, REP_SEQNUM_OFFSET);
|
|
649 set_header(curcmd->len, curcmd->pkt, REP_T_SIZE_OFFSET);
|
|
650 set_header(curcmd->lnum, curcmd->pkt, REP_LNUM_OFFSET);
|
|
651 }
|
|
652 return;
|
|
653 }
|
|
654
|
|
655 static int
|
|
656 rep_get_listened_fd()
|
|
657 {
|
|
658 int sock;
|
|
659 int value;
|
|
660 struct sockaddr_in addr;
|
|
661
|
|
662 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
663 e_msg_wrp("socket(): ERROR");
|
|
664 return(-1);
|
|
665 }
|
|
666
|
|
667 /* Allow other programs to bind to the socket */
|
|
668 value = 1;
|
|
669 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0) {
|
|
670 e_msg_wrp("setsockopt() REUSEADDR failed");
|
|
671 exit(1);
|
|
672 }
|
|
673
|
|
674 bzero((char*)&addr, sizeof(addr));
|
|
675
|
|
676 addr.sin_family = AF_INET;
|
|
677 addr.sin_addr.s_addr = INADDR_ANY;
|
|
678 addr.sin_port = htons(REP_PORT);
|
|
679
|
|
680 if ((bind(sock, (struct sockaddr*)&addr, sizeof(addr))) == -1) {
|
|
681 e_msg_wrp("bind(): ERROR");
|
|
682 return(-1);
|
|
683 }
|
|
684
|
|
685 if ((listen(sock, SOCK_MAX)) < 0) {
|
|
686 e_msg_wrp("listen(): ERROR");
|
|
687 return(-1);
|
|
688 }
|
|
689
|
|
690 return(sock);
|
|
691 }
|
|
692
|
|
693 static int
|
|
694 set_hostnamebysock(sock,hostname,maxlen)
|
|
695 int sock;
|
|
696 char *hostname;
|
|
697 int maxlen;
|
|
698 {
|
|
699 int sinlen;
|
|
700 struct sockaddr_in sin;
|
|
701 struct hostent *host;
|
|
702 int namelen;
|
|
703
|
|
704 sinlen = sizeof sin;
|
|
705 if (getpeername(sock, (struct sockaddr *) &sin, (socklen_t *)&sinlen) < 0){
|
|
706 return(FALSE);
|
|
707 }
|
|
708
|
|
709 if ((host = gethostbyaddr((char *) &sin.sin_addr, sizeof(sin.sin_addr), AF_INET)) == NULL){
|
|
710 return(FALSE);
|
|
711 }
|
|
712
|
|
713 namelen = strlen(host->h_name);
|
|
714 if (namelen > maxlen) {
|
|
715 e_msg_wrp("host name is too long.");
|
|
716 return(FALSE);
|
|
717 }
|
|
718
|
|
719 strncpy(hostname,host->h_name,namelen);
|
|
720 hostname[namelen] = '\0';
|
|
721 return(TRUE);
|
|
722 }
|
|
723
|
|
724 static char default_host[] = "localhost";
|
|
725
|
|
726 static int
|
|
727 rep_connect(host)
|
|
728 char *host; /* "hostname:portnumber" */
|
|
729 {
|
|
730 int sock;
|
|
731 struct hostent *hp;
|
|
732 struct sockaddr_in sin;
|
|
733 char *tmp;
|
|
734 int port;
|
|
735
|
|
736 if (host == NULL || host == '\n') {
|
|
737 host = default_host;
|
|
738 port = REP_PORT;
|
|
739 } else {
|
|
740 if ((tmp = strchr(host, ':')) == NULL ) {
|
|
741 return(-1);
|
|
742 }
|
|
743 *tmp = '\0';
|
|
744 tmp++;
|
|
745 port = atol(tmp);
|
|
746 }
|
|
747
|
|
748 if ((hp = gethostbyname(host)) == NULL) {
|
|
749 e_msg_wrp("rep_open: gethostbyname: ERROR");
|
|
750 return(-1);
|
|
751 }
|
|
752
|
|
753 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
754 e_msg_wrp("rep_open: socket : ERROR");
|
|
755 return(-1);
|
|
756 }
|
|
757
|
|
758 bzero(&sin, sizeof(sin));
|
|
759 sin.sin_family = AF_INET;
|
|
760 sin.sin_port = htons(port);
|
|
761 bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
|
|
762
|
|
763 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
|
764 e_msg_wrp("rep_open: connect: ERROR");
|
|
765 return(-1);
|
|
766 }
|
|
767
|
|
768 return(sock);
|
|
769 }
|
|
770
|
|
771
|
|
772 static BUFTYPE *
|
|
773 get_buf_by_name(name)
|
|
774 char *name;
|
|
775 {
|
|
776 BUFTYPE *buf;
|
|
777 if ((buf = find_buf_by_name_wrp(name)) == NULL) {
|
|
778 buf = make_new_buf_wrp(name);
|
|
779 }
|
|
780
|
|
781 if (buf && (buf->b_ml.ml_mfp == NULL)) {
|
|
782 open_buffer_memline_wrp(buf);
|
|
783 }
|
|
784
|
|
785 return buf;
|
|
786 }
|
|
787
|
|
788
|
|
789 /* About Session */
|
|
790
|
|
791 static Session *
|
|
792 init_session(sn)
|
|
793 Session *sn;
|
|
794 {
|
|
795 sn->next = NULL;
|
|
796 sn->buf = NULL;
|
|
797 sn->sname = NULL;
|
|
798 sn->new_cmdlist.head = NULL;
|
|
799 sn->new_cmdlist.num = 0;
|
|
800 sn->sent_cmdlist.head = NULL;
|
|
801 sn->sent_cmdlist.num = 0;
|
|
802 sn->sid = 0;
|
|
803 sn->permit = FALSE;
|
|
804 sn->prevline = -1;
|
|
805
|
|
806 return sn;
|
|
807 }
|
|
808
|
|
809 /*
|
|
810 * Make a new session.
|
|
811 * if buf is NULL, buffer is found or made new one.
|
|
812 */
|
|
813 static Session *
|
|
814 make_session(name, buf)
|
|
815 char *name;
|
|
816 BUFTYPE *buf;
|
|
817 {
|
|
818 Session *s;
|
|
819
|
|
820 char *sname;
|
|
821 int namelen = strlen(name)+1;
|
|
822
|
|
823 s = (Session*)rep_alloc(sizeof(Session));
|
|
824 if (s == NULL) {
|
|
825 return(NULL);
|
|
826 }
|
|
827
|
|
828 if ((sname = (char*)rep_alloc(namelen)) == NULL) {
|
|
829 return NULL;
|
|
830 }
|
|
831 strncpy(sname,name,namelen);
|
|
832
|
|
833 init_session(s);
|
|
834
|
|
835 if (buf == NULL) buf = get_buf_by_name(sname);
|
|
836 s->buf = buf;
|
|
837
|
|
838 s->sname = sname;
|
|
839
|
|
840 return s;
|
|
841 }
|
|
842
|
|
843 static void
|
|
844 free_session(sn)
|
|
845 Session *sn;
|
|
846 {
|
|
847
|
|
848 free_cmdlist(&sn->new_cmdlist);
|
|
849 free_cmdlist(&sn->sent_cmdlist);
|
|
850 free_buf_wrp(sn->buf);
|
|
851
|
|
852 if (sn->sname) rep_free(sn->sname);
|
|
853
|
|
854 init_session(sn);
|
|
855
|
|
856 rep_free(sn);
|
|
857 return;
|
|
858 }
|
|
859
|
|
860 static void
|
|
861 free_session_list(head)
|
|
862 Session *head;
|
|
863 {
|
|
864 Session *next;
|
|
865 for (; head; head=next) {
|
|
866 next = head->next;
|
|
867 head->next = NULL;
|
|
868 free_session(head);
|
|
869 }
|
|
870 return;
|
|
871 }
|
|
872
|
|
873 static void
|
|
874 register_session(sn)
|
|
875 Session *sn;
|
|
876 {
|
|
877 rep_T *rep;
|
|
878
|
|
879 rep = get_rep();
|
|
880
|
|
881 sn->next = rep->shead;
|
|
882 rep->shead = sn;
|
|
883
|
|
884 return;
|
|
885 }
|
|
886
|
|
887 static Session*
|
|
888 set_cursession(sn)
|
|
889 Session *sn;
|
|
890 {
|
|
891 BUFTYPE *oldbuf;
|
|
892 Session *oldsn;
|
|
893 rep_T *rep = get_rep();
|
|
894
|
|
895 if (sn) oldbuf = set_curbuf_wrp(sn->buf);
|
|
896 rep->cursession = sn;
|
|
897
|
|
898 oldsn = find_session_by_buf(oldbuf);
|
|
899 return oldsn;
|
|
900 }
|
|
901
|
|
902 static Session*
|
|
903 find_session_by_id(id)
|
|
904 unsigned int id;
|
|
905 {
|
|
906 Session *cursn = NULL;
|
|
907 rep_T *rep = get_rep();
|
|
908
|
|
909 if (rep->slineup && rep->slineup->sid == id) {
|
|
910 return rep->slineup;
|
|
911 }
|
|
912
|
|
913 for (cursn = rep->shead; cursn; cursn = cursn->next) {
|
|
914 if (cursn->sid == id) {
|
|
915 return cursn;
|
|
916 }
|
|
917 }
|
|
918
|
|
919 return NULL;
|
|
920 }
|
|
921
|
|
922 static Session*
|
|
923 find_session_by_buf(buf)
|
|
924 BUFTYPE *buf;
|
|
925 {
|
|
926 Session *cursn = NULL;
|
|
927 rep_T *rep = get_rep();
|
|
928
|
|
929 if (buf == NULL) return NULL;
|
|
930
|
|
931 if(rep->slineup->buf == buf)
|
|
932 return rep->slineup;
|
|
933 for (cursn = rep->shead; cursn; cursn = cursn->next) {
|
|
934 if (cursn->buf == buf) break;
|
|
935 }
|
|
936 return cursn;
|
|
937 }
|
|
938
|
|
939 static Session*
|
|
940 find_session_by_name(name)
|
|
941 char *name;
|
|
942 {
|
|
943 BUFTYPE *buf;
|
|
944 buf = find_buf_by_name_wrp(name);
|
|
945 return find_session_by_buf(buf);
|
|
946 }
|
|
947
|
|
948 int
|
|
949 rep_input_reg_session() // input own session(s)
|
|
950 {
|
|
951 char *sname;
|
|
952
|
|
953 while (1) {
|
|
954 // retrun value (sname) is allocated.
|
|
955 sname = getstr_input_wrp("Session to offer = ");
|
|
956 if (sname == NULL) return FALSE;
|
|
957 if (*sname=='\0') { // input pert is finished
|
|
958 free_wrp(sname);
|
|
959 break;
|
|
960 }
|
|
961 register_session(make_session(sname, NULL));
|
|
962
|
|
963 free_wrp(sname);
|
|
964 }
|
|
965
|
|
966 update_screen_now_wrp(); /* ウィンドウを再描画 */
|
|
967 return TRUE;
|
|
968 }
|
|
969
|
|
970
|
|
971 static int
|
|
972 set_session_info(dest_sinfo, sname, hostname, port)
|
|
973 char *dest_sinfo;
|
|
974 char *sname;
|
|
975 char *hostname;
|
|
976 int port;
|
|
977 {
|
|
978 int size;
|
|
979 size = sprintf(dest_sinfo, "%s:%d:%s",hostname, port, sname);
|
|
980 dest_sinfo[size] = '\0';
|
|
981 return 0;
|
|
982 }
|
|
983
|
|
984 static char*
|
|
985 get_fullpath(session)
|
|
986 Session *session;
|
|
987 {
|
|
988 BUFTYPE *buf;
|
|
989 if (session == NULL) {
|
|
990 buf = get_curbuf_wrp();
|
|
991 } else {
|
|
992 buf = session->buf;
|
|
993 }
|
|
994 return get_fullpath_wrp(buf);
|
|
995 }
|
|
996
|
|
997 static char*
|
|
998 get_shortname(session)
|
|
999 Session *session;
|
|
1000 {
|
|
1001 return get_shortname_wrp(session->buf);
|
|
1002 }
|
|
1003
|
|
1004
|
|
1005
|
|
1006 /* End Session */
|
|
1007
|
|
1008 #define SINFO_MAX 255
|
|
1009 /*
|
|
1010 * 自身が提供するセッションのみをセッションリストに書き出す
|
|
1011 * あらかじめセッションリストのバッファを編集対象のバッファに
|
|
1012 *指定しておく(set_curbuf_wrp(slineup)しておく)
|
|
1013 */
|
|
1014 static int
|
|
1015 make_local_slineup(slineup, hostname, my_sessions)
|
|
1016 Session *slineup;
|
|
1017 char *hostname;
|
|
1018 Session *my_sessions;
|
|
1019 {
|
|
1020 Session *s;
|
|
1021 BUFTYPE *oldcurbuf;
|
|
1022 char sinfo[SINFO_MAX];
|
|
1023
|
|
1024 if (my_sessions == NULL) return FALSE;
|
|
1025
|
|
1026 for (; my_sessions; my_sessions=my_sessions->next) {
|
|
1027 set_session_info(sinfo, my_sessions->sname, hostname, REP_PORT);
|
|
1028 /* 現在の編集対象のバッファ curbuf に対して書き込みを行なう */
|
|
1029 append_memline_wrp(1, sinfo);
|
|
1030 }
|
|
1031
|
|
1032 return TRUE;
|
|
1033 }
|
|
1034
|
|
1035
|
|
1036 /*
|
|
1037 * セッションマネージャからセッションリストを取得
|
|
1038 * あらかじめセッションリストのバッファを編集対象のバッファに
|
|
1039 *指定しておく(set_curbuf_wrp(buf)しておく)
|
|
1040 */
|
|
1041 static int
|
|
1042 get_slineup_from_sm(servername, slineup, hostname, my_sessions)
|
|
1043 char *servername;
|
|
1044 Session *slineup;
|
|
1045 char *hostname;
|
|
1046 Session *my_sessions; // linked list
|
|
1047 {
|
|
1048 return TRUE;
|
|
1049 }
|
|
1050
|
|
1051
|
|
1052 char *
|
|
1053 rep_input_param(msg, err_msg)
|
|
1054 char *msg;
|
|
1055 char *err_msg;
|
|
1056 {
|
|
1057 char *input_string;
|
|
1058
|
|
1059 if ((input_string = getstr_input_wrp(msg)) == NULL) {
|
|
1060 return NULL;
|
|
1061 }
|
|
1062
|
|
1063 if (*input_string == '\0') {
|
|
1064 if (err_msg) {
|
|
1065 puts_msg_wrp(err_msg);
|
|
1066 }
|
|
1067 free_wrp(input_string);
|
|
1068 return NULL;
|
|
1069 }
|
|
1070
|
|
1071 return input_string;
|
|
1072 }
|
|
1073
|
|
1074 int
|
|
1075 rep_join()
|
|
1076 {
|
|
1077 int sock;
|
|
1078 rep_T *rep;
|
|
1079
|
|
1080 rep_cmdlist cmdlist = {NULL,0};
|
|
1081
|
|
1082 rep = get_rep();
|
|
1083 /*
|
|
1084 if (server == NULL) {
|
|
1085 return FALSE;
|
|
1086 }
|
|
1087 */
|
|
1088 if ((sock = rep_connect(NULL)) < 0) {
|
|
1089 return FALSE;
|
|
1090 }
|
|
1091 if (rep->smfd > 0) {
|
|
1092 close(rep->smfd);
|
|
1093 }
|
|
1094
|
|
1095 rep->smfd = sock;
|
|
1096 rep->permit = TRUE;
|
|
1097
|
11
|
1098 add_cmd_to_list(&cmdlist, make_cmd(REP_JOIN_CMD, 0, rep->eid, rep->seqno++, 0, "bufname"));
|
8
|
1099 rep_send_cmds(sock, &cmdlist);
|
|
1100
|
|
1101 free_cmdlist(&cmdlist);
|
|
1102
|
|
1103 return TRUE;
|
|
1104
|
|
1105 }
|
|
1106
|
|
1107 int
|
|
1108 rep_select_command(session_no)
|
|
1109 char *session_no;
|
|
1110 {
|
|
1111 rep_T *rep = get_rep();
|
|
1112 rep_cmdlist cmdlist = {NULL, 0};
|
|
1113 int sid;
|
|
1114
|
|
1115
|
|
1116 if (rep->smfd < 0 || session_no == NULL) {
|
|
1117 return FALSE;
|
|
1118 }
|
|
1119
|
|
1120 if (rep->waiting_session_name) {
|
|
1121 rep_free(rep->waiting_session_name);
|
|
1122 }
|
|
1123 sid = atol(session_no);
|
|
1124 if ((rep->waiting_session_name = get_sname_by_snum(sid)) == NULL) {
|
|
1125 e_msg_wrp("Session Selection is false.");
|
|
1126 return FALSE;
|
|
1127 }
|
|
1128
|
|
1129 add_cmd_to_list(&cmdlist, make_cmd(REP_SELECT_CMD, sid, rep->eid, rep->seqno++, 0, session_no));
|
|
1130 rep_send_cmds(rep->smfd, &cmdlist);
|
|
1131
|
|
1132 free_cmdlist(&cmdlist);
|
|
1133
|
|
1134 return TRUE;
|
|
1135 }
|
|
1136
|
|
1137 int
|
|
1138 rep_put(sname)
|
|
1139 char *sname;
|
|
1140 {
|
|
1141 int sock;
|
|
1142 rep_T *rep = get_rep();
|
|
1143 rep_cmdlist cmdlist = {NULL, 0};
|
|
1144 int len;
|
|
1145 Session *sn;
|
|
1146
|
|
1147 if ((sock = rep_connect(NULL)) < 0) {
|
|
1148 return FALSE;
|
|
1149 }
|
|
1150 if (rep->smfd > 0) {
|
|
1151 close(rep->smfd);
|
|
1152 }
|
|
1153
|
|
1154 rep->smfd = sock;
|
|
1155 rep->permit = TRUE;
|
|
1156
|
|
1157 if (sname == NULL) {
|
|
1158 /* get current buffer name */
|
|
1159 if ((sname = get_fullpath(rep->cursession)) == NULL) {
|
|
1160 sname = NO_NAME; /* the buffer has not name */
|
|
1161 }
|
|
1162 }
|
|
1163
|
|
1164 /*
|
|
1165 if (find_session_by_name(sname) == NULL) {
|
|
1166 sn = make_session(sname, get_buf_by_name(sname));
|
|
1167 register_session(sn);
|
|
1168 }
|
|
1169 */
|
|
1170
|
|
1171
|
|
1172 if (rep->waiting_session_name) {
|
|
1173 rep_free(rep->waiting_session_name);
|
|
1174 }
|
|
1175 len = strlen(sname) +1;
|
|
1176 rep->waiting_session_name = (char *)rep_alloc(len);
|
|
1177 memcpy(rep->waiting_session_name, sname, len);
|
|
1178
|
|
1179 add_cmd_to_list(&cmdlist, make_cmd(REP_PUT_CMD, 0, rep->eid, rep->seqno++, 0, sname));
|
|
1180
|
|
1181 rep_send_cmds(rep->smfd, &cmdlist);
|
|
1182
|
|
1183 free_cmdlist(&cmdlist);
|
|
1184
|
|
1185 return TRUE;
|
|
1186 }
|
|
1187
|
|
1188
|
|
1189 int
|
|
1190 rep_remove()
|
|
1191 {
|
|
1192 rep_T *rep = get_rep();
|
|
1193 rep_cmd *cmd;
|
|
1194 rep_cmdlist cmdlist = {NULL, 0};
|
|
1195 Session *sn = rep->cursession;
|
|
1196
|
|
1197 if (rep->smfd < 0) { /* session does not exist */
|
|
1198 EMSG("Session does not exist.");
|
|
1199 return FALSE;
|
|
1200 }
|
|
1201
|
|
1202 cmd = make_cmd(REP_DEREGISTER_CMD, sn->sid, rep->eid, rep->seqno, 0, NULL);
|
|
1203 add_cmd_to_list(&cmdlist, cmd);
|
|
1204 rep_send_cmds(rep->smfd, &cmdlist);
|
|
1205 free_cmdlist(&cmdlist);
|
|
1206
|
|
1207 return TRUE;
|
|
1208 }
|
|
1209
|
|
1210 static int
|
|
1211 rep_make_slineup()
|
|
1212 {
|
|
1213 BUFTYPE buf;
|
|
1214 // BUFTYPE *oldcurbuf;
|
|
1215 Session *oldsn;
|
|
1216
|
|
1217 rep_T *rep;
|
|
1218 rep = get_rep();
|
|
1219
|
|
1220 if (rep->slineup) {
|
|
1221 free_session(rep->slineup);
|
|
1222 }
|
|
1223
|
|
1224 rep->slineup = make_session(SLINEUP_NAME, make_new_buf_wrp(SLINEUP_NAME));
|
|
1225
|
|
1226 oldsn = set_cursession(rep->slineup);
|
|
1227
|
|
1228 /* セッション一覧リストを作成 */
|
|
1229 if ((get_slineup_from_sm(rep->servername, rep->slineup, rep->hostname, rep->shead) == FALSE)) {
|
|
1230 make_local_slineup(rep->slineup, rep->hostname, rep->shead);
|
|
1231 }
|
|
1232
|
|
1233 update_screen_now_wrp(); /* ウィンドウを再描画 */
|
|
1234
|
|
1235 return TRUE;
|
|
1236 }
|
|
1237
|
|
1238
|
|
1239 static int
|
|
1240 enter_session(session_name)
|
|
1241 char *session_name;
|
|
1242 {
|
|
1243 return TRUE;
|
|
1244 }
|
|
1245
|
|
1246
|
|
1247 /* Session End */
|
|
1248
|
|
1249 static void *
|
|
1250 rep_alloc(size)
|
|
1251 int size; /* byte */
|
|
1252 {
|
|
1253 void *allocated;
|
|
1254 if ((allocated = malloc(size)) == NULL) {
|
|
1255 e_msg_wrp("no memory!");
|
|
1256 }
|
|
1257
|
|
1258 return allocated;
|
|
1259 }
|
|
1260
|
|
1261 static void
|
|
1262 rep_free(obj)
|
|
1263 void *obj;
|
|
1264 {
|
|
1265 if (obj) free(obj);
|
|
1266 return;
|
|
1267 }
|
|
1268
|
|
1269
|
|
1270 static int
|
|
1271 writen(sock, pkt, len)
|
|
1272 int sock;
|
|
1273 char *pkt;
|
|
1274 unsigned int len;
|
|
1275 {
|
|
1276 int offset;
|
|
1277 int written;
|
|
1278
|
|
1279 if (len == 0) return 0;
|
|
1280
|
|
1281 for (offset=0, written=0; offset<len; offset += written) {
|
|
1282 if ((written = write(sock, pkt + offset, len - offset)) < 0) {
|
|
1283 puts_sys_err();
|
|
1284 return written;
|
|
1285 }
|
|
1286 }
|
|
1287 return offset;
|
|
1288 }
|
|
1289
|
|
1290 static int
|
|
1291 readn(sock, pkt, len)
|
|
1292 int sock;
|
|
1293 char *pkt;
|
|
1294 unsigned int len;
|
|
1295 {
|
|
1296 unsigned int r;
|
|
1297 unsigned int offset;
|
|
1298
|
|
1299 if (len == 0) return 0;
|
|
1300
|
|
1301 for (offset=0, r=0; offset<len; offset += r) {
|
|
1302 if ((r = read(sock, pkt + offset, len - offset)) < 0) {
|
|
1303 puts_sys_err();
|
|
1304 return r;
|
|
1305 }
|
|
1306 }
|
|
1307 return offset;
|
|
1308 }
|
|
1309
|
|
1310
|
|
1311 static char*
|
|
1312 make_packet(cmd, sid, eid, seq, lnum, text)
|
|
1313 unsigned int cmd;
|
|
1314 unsigned int sid;
|
|
1315 unsigned int eid;
|
|
1316 unsigned int seq;
|
|
1317 unsigned int lnum;
|
|
1318 char * text;
|
|
1319 {
|
|
1320 char *packet;
|
|
1321 unsigned int len = 0;
|
|
1322
|
|
1323 if (text) len += strlen(text);// + 1; /* for include '\0' */
|
|
1324
|
|
1325 if ((packet = (char *)rep_alloc(REP_HEADER_SIZE+len)) == NULL) {
|
|
1326 return(NULL);
|
|
1327 }
|
|
1328
|
|
1329 set_header(cmd, packet, REP_CMD_OFFSET);
|
|
1330 set_header(sid, packet, REP_SID_OFFSET);
|
|
1331 set_header(eid, packet, REP_EID_OFFSET);
|
|
1332 set_header(seq, packet, REP_SEQNUM_OFFSET);
|
|
1333 set_header(lnum, packet, REP_LNUM_OFFSET);
|
|
1334 set_header(len, packet, REP_T_SIZE_OFFSET);
|
|
1335
|
|
1336 if (text) {
|
|
1337 memcpy(packet+REP_TEXT_OFFSET, text, len);
|
|
1338 }
|
|
1339
|
|
1340 return(packet);
|
|
1341 }
|
|
1342
|
|
1343
|
|
1344 static rep_cmd*
|
|
1345 make_cmd(cmd, sid, eid, seq, lnum, text)
|
|
1346 unsigned int cmd;
|
|
1347 unsigned int sid;
|
|
1348 unsigned int eid;
|
|
1349 unsigned int seq;
|
|
1350 unsigned int lnum;
|
|
1351 char *text;
|
|
1352 {
|
|
1353 rep_cmd *cmd_p;
|
|
1354 char *pkt;
|
|
1355 unsigned int length = 0;
|
|
1356
|
|
1357 pkt = make_packet(cmd, sid, eid, seq, lnum, text);
|
|
1358 if (pkt == NULL) {
|
|
1359 e_msg_wrp("make_cmd: no memory: ERROR");
|
|
1360 return(NULL);
|
|
1361 }
|
|
1362
|
|
1363 cmd_p = (rep_cmd*)rep_alloc(sizeof(rep_cmd));
|
|
1364 if (cmd_p == NULL) {
|
|
1365 e_msg_wrp("make_cmd: no memory: ERROR");
|
|
1366 return(NULL);
|
|
1367 }
|
|
1368
|
|
1369 if (text) {
|
|
1370 length = strlen(text); //+1; // include '\0'
|
|
1371 }
|
|
1372
|
|
1373 cmd_p->next = NULL;
|
|
1374
|
|
1375 cmd_p->cmd = cmd;
|
|
1376 cmd_p->sid = sid;
|
|
1377 cmd_p->eid = eid;
|
|
1378 cmd_p->seq = seq;
|
|
1379 cmd_p->len = length;
|
|
1380 cmd_p->lnum = lnum;
|
|
1381
|
|
1382 cmd_p->stat = REP_AVAIL;
|
|
1383 cmd_p->pkt = pkt;
|
|
1384
|
|
1385 return(cmd_p);
|
|
1386 }
|
|
1387
|
|
1388 static int
|
|
1389 free_cmd(cmd)
|
|
1390 rep_cmd *cmd;
|
|
1391 {
|
|
1392 if (cmd == NULL) return(FALSE);
|
|
1393
|
|
1394 if (cmd->pkt) {
|
|
1395 rep_free(cmd->pkt);
|
|
1396 cmd->pkt=NULL;
|
|
1397 }
|
|
1398 rep_free(cmd);
|
|
1399 cmd = 0;
|
|
1400 return(TRUE);
|
|
1401 }
|
|
1402
|
|
1403 static int
|
|
1404 free_cmdlist(cmdlist)
|
|
1405 rep_cmdlist *cmdlist;
|
|
1406 {
|
|
1407 rep_cmd *cur;
|
|
1408 rep_cmd *next;
|
|
1409
|
|
1410 if (cmdlist->head==NULL) return(FALSE);
|
|
1411 for (cur=cmdlist->head; cur; cur=next) {
|
|
1412 next=cur->next;
|
|
1413 free_cmd(cur);
|
|
1414 }
|
|
1415 cmdlist->head = NULL;
|
|
1416 cmdlist->num = 0;
|
|
1417 return(TRUE);
|
|
1418 }
|
|
1419
|
|
1420 static void
|
|
1421 add_cmd_to_list(cmdlist, cmd)
|
|
1422 rep_cmdlist *cmdlist;
|
|
1423 rep_cmd *cmd;
|
|
1424 {
|
|
1425 rep_cmd *p;
|
|
1426 int count = 0;
|
|
1427
|
|
1428 for (p=cmd; p; p=p->next) count++;
|
|
1429
|
|
1430 if (cmdlist->head) {
|
|
1431 for (p = cmdlist->head; p->next; p = p->next);
|
|
1432 p->next = cmd;
|
|
1433 } else {
|
|
1434 cmdlist->head = cmd;
|
|
1435 }
|
|
1436 cmdlist->num += count;
|
|
1437 return;
|
|
1438 }
|
|
1439
|
|
1440 static int
|
|
1441 add_pkt_to_list(cmdlist, pkt) /* pkt is allocated */
|
|
1442 rep_cmdlist *cmdlist;
|
|
1443 char *pkt;
|
|
1444 {
|
|
1445 rep_cmd *cmd_p;
|
|
1446
|
|
1447 if (pkt == NULL) return(FALSE);
|
|
1448
|
|
1449 cmd_p = (rep_cmd*)rep_alloc(sizeof(rep_cmd));
|
|
1450 if (cmd_p == NULL) {
|
|
1451 e_msg_wrp("add_pkt_to_list: no memory: ERROR");
|
|
1452 return(FALSE);
|
|
1453 }
|
|
1454
|
|
1455 cmd_p->next = NULL;
|
|
1456
|
|
1457 cmd_p->cmd = get_header(pkt, REP_CMD_OFFSET);
|
|
1458 cmd_p->sid = get_header(pkt, REP_SID_OFFSET);
|
|
1459 cmd_p->eid = get_header(pkt, REP_EID_OFFSET);
|
|
1460 cmd_p->seq = get_header(pkt, REP_SEQNUM_OFFSET);
|
|
1461 cmd_p->lnum = get_header(pkt, REP_LNUM_OFFSET);
|
|
1462
|
|
1463 cmd_p->stat = REP_AVAIL;
|
|
1464 cmd_p->len = strlen(pkt)+1 - REP_HEADER_SIZE;
|
|
1465 cmd_p->pkt = pkt;
|
|
1466
|
|
1467 add_cmd_to_list(cmdlist, cmd_p);
|
|
1468
|
|
1469 return(TRUE);
|
|
1470 }
|
|
1471
|
|
1472
|
|
1473 void
|
|
1474 rep_prevline_flush()
|
|
1475 {
|
|
1476 BUFTYPE *cbuf;
|
|
1477 Session *cursn;
|
|
1478 rep_cmd *cmd;
|
|
1479 rep_T *rep = get_rep();
|
|
1480 char *text;
|
|
1481
|
|
1482 cursn = rep->cursession;
|
|
1483
|
|
1484 if ((cursn == NULL) || (cursn->prevline == -1)) return;
|
|
1485
|
|
1486 // バッファが変更された場合には rep->cursession も合わす
|
|
1487 if ((cbuf = get_curbuf_wrp()) != cursn->buf) {
|
|
1488 cursn = find_session_by_buf(cbuf);
|
|
1489 if (cursn == NULL)
|
|
1490 return;
|
|
1491 rep->cursession = cursn;
|
|
1492 }
|
|
1493
|
|
1494 text = get_memline_wrp(cursn->buf, cursn->prevline);
|
|
1495
|
12
|
1496 //cmd = make_cmd(REP_REPLACE_CMD, cursn->sid, rep->eid, rep->seqno++, cursn->prevline, text);
|
|
1497
|
|
1498 // TODO : 変更前のテキストを UNDO バッファから取得する
|
|
1499 cmd = make_cmd(REP_DELETE_CMD, cursn->sid, rep->eid, rep->seqno++, cursn->prevline, prev_text);
|
|
1500 cmd->next = make_cmd(REP_INSERT_CMD, cursn->sid, rep->eid, rep->seqno++, cursn->prevline, text);
|
8
|
1501
|
|
1502 add_cmd_to_list(&(cursn->new_cmdlist), cmd);
|
|
1503
|
|
1504
|
|
1505
|
|
1506 if (cursn->sent_cmdlist.num == 0) { // 自トークンを送信してない場合
|
|
1507 rep_send_cur_cmdlist();
|
|
1508 }
|
|
1509
|
|
1510 cursn->prevline = -1;
|
|
1511 }
|
|
1512
|
|
1513
|
|
1514 static void
|
|
1515 check_line_change(sn, lnum)
|
|
1516 Session *sn;
|
|
1517 unsigned int lnum;
|
|
1518 {
|
|
1519 rep_cmd *cmd;
|
|
1520 rep_T *rep = get_rep();
|
|
1521
|
|
1522
|
|
1523 if (sn->prevline == lnum) {
|
|
1524 return;
|
|
1525 }
|
|
1526
|
|
1527 if (sn->prevline == -1) {
|
|
1528 sn->prevline = lnum;
|
|
1529 return;
|
|
1530 }
|
|
1531 cmd = make_cmd(REP_REPLACE_CMD, sn->sid, rep->eid, rep->seqno++, sn->prevline,
|
|
1532 get_memline_wrp(sn->buf, sn->prevline));
|
|
1533 add_cmd_to_list(&(sn->new_cmdlist), cmd);
|
|
1534
|
|
1535 sn->prevline = lnum;
|
|
1536 return;
|
|
1537 }
|
|
1538
|
|
1539 int
|
|
1540 rep_register(lnum, lnume, xtra)
|
|
1541 unsigned int lnum;
|
|
1542 unsigned int lnume;
|
|
1543 int xtra;
|
|
1544 {
|
|
1545 int i;
|
|
1546 BUFTYPE *cbuf;
|
|
1547 Session *cursn;
|
|
1548 rep_cmd *cmd;
|
|
1549 rep_T *rep = get_rep();
|
|
1550
|
|
1551 if ((cursn = rep->cursession) == NULL) return FALSE;
|
|
1552
|
|
1553 // バッファが変更された場合には rep->cursession も合わす
|
|
1554 if ((cbuf = get_curbuf_wrp()) != cursn->buf) {
|
|
1555 cursn = find_session_by_buf(cbuf);
|
|
1556 if (cursn == NULL)
|
|
1557 return FALSE;
|
|
1558 rep->cursession = cursn;
|
|
1559 }
|
|
1560
|
|
1561 if (xtra == 0) {
|
|
1562 for (i = 0; lnume-lnum > i; i++) {
|
|
1563 check_line_change(cursn,lnum+i);
|
|
1564 }
|
|
1565 } else if (xtra > 0) {
|
|
1566 if (lnum != lnume) { /* 行の途中から改行 */
|
|
1567 cmd = make_cmd( REP_REPLACE_CMD, cursn->sid, rep->eid, rep->seqno++, lnum,
|
|
1568 get_memline_wrp(cursn->buf, lnum));
|
|
1569 add_cmd_to_list(&(cursn->new_cmdlist), cmd);
|
|
1570 lnum++;
|
|
1571 }
|
|
1572 for (i = 0; xtra > 0; i++, xtra--) {
|
|
1573 cmd = make_cmd( REP_INSERT_CMD, cursn->sid, rep->eid, rep->seqno++, lnum+i,
|
|
1574 get_memline_wrp(cursn->buf, lnum+i));
|
|
1575 add_cmd_to_list(&(cursn->new_cmdlist), cmd);
|
|
1576 }
|
|
1577 } else { /* xtra < 0 */
|
|
1578 xtra = -xtra;
|
|
1579 for (; xtra > 0; xtra--) {
|
|
1580 cmd = make_cmd(REP_DELETE_LINE_CMD, cursn->sid, rep->eid, rep->seqno++, lnum,
|
|
1581 NULL);
|
|
1582 add_cmd_to_list(&(cursn->new_cmdlist), cmd);
|
|
1583 }
|
|
1584 }
|
|
1585
|
|
1586 if (cursn->sent_cmdlist.num == 0) {
|
|
1587 rep_send_cur_cmdlist();
|
|
1588 }
|
|
1589
|
|
1590 return(lnume - lnum);
|
|
1591 }
|
|
1592
|
|
1593
|
|
1594 static int
|
|
1595 set_header(data, pkt, offset)
|
|
1596 unsigned int data;
|
|
1597 char *pkt;
|
|
1598 int offset;
|
|
1599 {
|
|
1600 int *ipkt;
|
|
1601 int ndata = htonl(data);
|
|
1602
|
|
1603 ipkt = (int*)pkt;
|
|
1604 ipkt[offset/4] = ndata;
|
|
1605
|
|
1606 return(TRUE);
|
|
1607 }
|
|
1608
|
|
1609 static unsigned int
|
|
1610 get_header(pkt, offset)
|
|
1611 char *pkt;
|
|
1612 int offset;
|
|
1613 {
|
|
1614 int *ipkt;
|
|
1615 int data;
|
|
1616 unsigned int header;
|
|
1617
|
|
1618 ipkt = (int *)pkt;
|
|
1619 data = ipkt[offset/4];
|
|
1620 header = (unsigned int)ntohl(data);
|
|
1621
|
|
1622 return(header);
|
|
1623 }
|
|
1624
|
|
1625
|
|
1626 static int
|
|
1627 rep_exe_cmd(cmd, sid, eid, seq, lnum, textsize, text)
|
|
1628 unsigned int cmd;
|
|
1629 unsigned int sid;
|
|
1630 unsigned int eid;
|
|
1631 unsigned int seq;
|
|
1632 unsigned int lnum;
|
|
1633 unsigned int textsize;
|
|
1634 char *text;
|
|
1635 {
|
|
1636 char h_name[50];
|
|
1637 rep_cmdlist tmplist = {NULL, 0};
|
|
1638 rep_cmd *repcmd;
|
|
1639 BUFTYPE *buf;
|
|
1640 rep_T *rep = get_rep();
|
|
1641 Session *session;
|
|
1642
|
|
1643 unsigned int buflenmax;
|
|
1644
|
|
1645 session = find_session_by_id(sid);
|
|
1646
|
|
1647 /*XXX 無理矢理 */
|
|
1648 if (textsize == 0) {
|
|
1649 text = NULL;
|
|
1650 }
|
|
1651
|
|
1652 switch (cmd) {
|
|
1653 case REP_JOIN_ACK:
|
|
1654 /* show session lineup */
|
|
1655 if (rep->slineup) {
|
|
1656 free_session(rep->slineup);
|
|
1657 }
|
|
1658 rep->slineup = make_session(SLINEUP_NAME, make_new_buf_wrp(SLINEUP_NAME));
|
|
1659 append_newline_sep_text(rep->slineup, text);
|
|
1660 set_cursession(rep->slineup);
|
|
1661 update_screen_now_wrp();
|
|
1662
|
|
1663 if (rep->eid == 0) {
|
|
1664 rep->eid = eid;
|
|
1665 }
|
|
1666 break;
|
12
|
1667 /*
|
8
|
1668 case REP_SELECT_ACK:
|
|
1669 // text is error message. means occur ERROR in session manager
|
|
1670 if (text) {
|
|
1671 e_msg_wrp(text);
|
|
1672 return FALSE;
|
|
1673 }
|
|
1674
|
|
1675 // DON'T wait session from session manager
|
|
1676 if (! rep->waiting_session_name) {
|
|
1677 return FALSE;
|
|
1678 }
|
|
1679
|
|
1680 session = make_session(rep->waiting_session_name,
|
|
1681 make_new_buf_wrp(rep->waiting_session_name));
|
|
1682 session->sid = sid;
|
|
1683 register_session(session);
|
|
1684
|
|
1685 rep_free(rep->waiting_session_name);
|
|
1686 rep->waiting_session_name = NULL;
|
|
1687
|
|
1688 set_cursession(session);
|
|
1689
|
|
1690 rep_start_create_cmds();
|
|
1691
|
12
|
1692 // get window size
|
|
1693 // send read command
|
8
|
1694 break;
|
|
1695 case REP_REGISTER_ACK:
|
12
|
1696 */
|
8
|
1697 case REP_PUT_ACK:
|
|
1698 /* Enter Session */
|
|
1699
|
|
1700 if (text) { // text is error message.
|
|
1701 e_msg_wrp(text);
|
|
1702 return FALSE;
|
|
1703 }
|
|
1704
|
|
1705 /* Use wating_session_name for assign session id */
|
|
1706 if ((session = find_session_by_name(rep->waiting_session_name)) == NULL) {
|
|
1707 if (rep->waiting_session_name) {
|
|
1708 rep_free(rep->waiting_session_name);
|
|
1709 rep->waiting_session_name = NULL;
|
|
1710 }
|
|
1711 return FALSE;
|
|
1712 }
|
|
1713 session->sid = sid;
|
|
1714
|
|
1715 /* set session to cursession */
|
|
1716 set_cursession(session);
|
|
1717 rep_start_create_cmds();
|
|
1718
|
|
1719 break;
|
12
|
1720 /*
|
8
|
1721 case REP_DEREGISTER_CMD:
|
|
1722 case REP_DEREGISTER_ACK:
|
|
1723 case REP_QUIT_CMD:
|
|
1724 case REP_QUIT_ACK:
|
|
1725 case REP_GET_CMD:
|
|
1726 case REP_GET_ACK:
|
|
1727 break;
|
|
1728 case REP_OPEN_CMD:
|
12
|
1729 // REP_OPEN_CMD is handled in list part. (may be upper function)
|
8
|
1730 break;
|
|
1731
|
|
1732 case REP_OPEN_ACK:
|
|
1733 case REP_CLOSE_CMD:
|
|
1734 break;
|
|
1735 case REP_CLOSE_ACK:
|
|
1736 break;
|
|
1737 case REP_READ_CMD:
|
|
1738 break;
|
|
1739 case REP_READ_ACK:
|
|
1740 break;
|
|
1741 case REP_READ_FIN:
|
|
1742 break;
|
12
|
1743 // buffer edit commands
|
|
1744 // session's buffer is set to current buffer
|
|
1745 */
|
8
|
1746 case REP_INSERT_CMD:
|
|
1747 append_memline_wrp(lnum, text);
|
|
1748 break;
|
|
1749 case REP_DELETE_LINE_CMD:
|
|
1750 delete_memline_wrp(lnum);
|
|
1751 break;
|
12
|
1752 /*
|
8
|
1753 case REP_REPLACE_CMD:
|
|
1754 if (lnum > get_bufmaxline_wrp(session->buf)) {
|
|
1755 append_memline_wrp(lnum, text);
|
|
1756 }
|
12
|
1757 replace_memline_wrp(lnum, text); // text was allocated
|
8
|
1758 break;
|
12
|
1759 */
|
8
|
1760 default:
|
|
1761 break;
|
|
1762 }
|
|
1763
|
|
1764 free_cmdlist(&(tmplist));
|
|
1765
|
|
1766 return(TRUE);
|
|
1767 }
|
|
1768
|
|
1769
|
|
1770 static int
|
|
1771 rep_exe_pkt(pkt)
|
|
1772 char *pkt;
|
|
1773 {
|
|
1774 unsigned int cmd;
|
|
1775 unsigned int sid;
|
|
1776 unsigned int eid;
|
|
1777 unsigned int seq;
|
|
1778 unsigned int lnum;
|
|
1779 unsigned int len;
|
|
1780 char *text;
|
|
1781
|
|
1782 cmd = get_header(pkt, REP_CMD_OFFSET);
|
|
1783 sid = get_header(pkt, REP_SID_OFFSET);
|
|
1784 eid = get_header(pkt, REP_EID_OFFSET);
|
|
1785 seq = get_header(pkt, REP_SEQNUM_OFFSET);
|
|
1786 lnum = get_header(pkt, REP_LNUM_OFFSET);
|
|
1787 len = get_header(pkt, REP_T_SIZE_OFFSET);
|
|
1788 text = pkt + REP_TEXT_OFFSET;
|
|
1789
|
|
1790 rep_exe_cmd(cmd, sid, eid, seq, lnum, len, text);
|
|
1791
|
|
1792 return(TRUE);
|
|
1793 }
|
|
1794
|
|
1795 /* execute command list based cmd packet */
|
|
1796 static int
|
|
1797 rep_exe_pktlist(cmdlist)
|
|
1798 rep_cmdlist *cmdlist;
|
|
1799 {
|
|
1800 rep_cmd *repcmd;
|
|
1801 BUFTYPE *orgbuf;
|
|
1802 char *sname;
|
|
1803
|
|
1804 if ((cmdlist == NULL) || (cmdlist->head == NULL)) {
|
|
1805 return(FALSE);
|
|
1806 }
|
|
1807
|
|
1808 for (repcmd = cmdlist->head; repcmd; repcmd = repcmd->next) {
|
|
1809 if (repcmd->stat == REP_AVAIL) {
|
|
1810 rep_exe_pkt(repcmd->pkt);
|
|
1811 }
|
|
1812 }
|
|
1813
|
|
1814 return(TRUE);
|
|
1815 }
|
|
1816
|
|
1817
|
|
1818 /* execute command list based cmd structure */
|
|
1819 /* sn must be already exists */
|
|
1820 static int
|
|
1821 rep_exe_cmdlist(cmdlist)
|
|
1822 rep_cmdlist *cmdlist;
|
|
1823 {
|
|
1824 rep_cmd *cmd;
|
|
1825 BUFTYPE *orgbuf;
|
|
1826 unsigned short uid;
|
|
1827
|
|
1828 if ((cmdlist == NULL) || (cmdlist->head == NULL)) {
|
|
1829 return(FALSE);
|
|
1830 }
|
|
1831
|
|
1832 for (cmd = cmdlist->head; cmd; cmd = cmd->next) {
|
|
1833 if (cmd->stat == REP_AVAIL) {
|
|
1834 rep_exe_cmd(cmd->cmd, cmd->sid, cmd->eid, cmd->seq,
|
|
1835 cmd->lnum, cmd->len, cmd->pkt + REP_TEXT_OFFSET);
|
|
1836 }
|
|
1837 }
|
|
1838
|
|
1839 return(TRUE);
|
|
1840 }
|
|
1841
|
|
1842
|
|
1843
|
|
1844
|
|
1845 static int
|
|
1846 rep_recv_cmds(fd, smcmdlist, txtcmdlist)
|
|
1847 int fd;
|
|
1848 rep_cmdlist *smcmdlist;
|
|
1849 rep_cmdlist *txtcmdlist;
|
|
1850 {
|
|
1851 unsigned int cmd;
|
|
1852 unsigned int sid;
|
|
1853 unsigned int eid;
|
|
1854 unsigned int seq;
|
|
1855 unsigned int lnum;
|
|
1856 unsigned int textsize;
|
|
1857
|
|
1858 char header[REP_HEADER_SIZE];
|
|
1859
|
|
1860 char *text = NULL;
|
|
1861 int retval;
|
|
1862
|
|
1863 if (fd < 0) {
|
|
1864 return(FALSE);
|
|
1865 }
|
|
1866
|
|
1867 /* 一定時間読み取るようにしたい */
|
|
1868
|
|
1869 /* read header part */
|
|
1870 if (readn(fd, header, REP_HEADER_SIZE) < 0) {
|
|
1871 puts_sys_err();
|
|
1872 return(FALSE);
|
|
1873 }
|
|
1874
|
|
1875 cmd = get_header(header, REP_CMD_OFFSET);
|
|
1876 sid = get_header(header, REP_SID_OFFSET);
|
|
1877 eid = get_header(header, REP_EID_OFFSET);
|
|
1878 seq = get_header(header, REP_SEQNUM_OFFSET);
|
|
1879 lnum = get_header(header, REP_LNUM_OFFSET);
|
|
1880 textsize = get_header(header, REP_T_SIZE_OFFSET);
|
|
1881
|
|
1882 if (textsize > 0) {
|
|
1883 if ((text = (char*)rep_alloc(textsize)) == NULL) {
|
|
1884 return(FALSE);
|
|
1885 }
|
|
1886 /* read text part */
|
|
1887 if (readn(fd, text, textsize) < 0) {
|
|
1888 puts_sys_err();
|
|
1889 rep_free(text);
|
|
1890 return(FALSE);
|
|
1891 }
|
|
1892 }
|
|
1893
|
|
1894 if (cmd == REP_INSERT_CMD ||
|
|
1895 cmd == REP_DELETE_LINE_CMD ||
|
|
1896 cmd == REP_REPLACE_CMD) {
|
|
1897 add_cmd_to_list(txtcmdlist, make_cmd(cmd, sid, eid, seq, lnum, text));
|
|
1898 } else {
|
|
1899 add_cmd_to_list(smcmdlist, make_cmd(cmd, sid, eid, seq, lnum, text));
|
|
1900 }
|
|
1901 return(TRUE);
|
|
1902 }
|
|
1903
|
|
1904 void
|
|
1905 rep_send_cur_cmdlist()
|
|
1906 {
|
|
1907 rep_T *rep_p = get_rep();
|
|
1908
|
|
1909 rep_send_cmds(rep_p->smfd,&(rep_p->cursession->new_cmdlist));
|
|
1910
|
|
1911 free_cmdlist(&rep_p->cursession->sent_cmdlist);
|
|
1912
|
|
1913 rep_p->cursession->sent_cmdlist.head = rep_p->cursession->new_cmdlist.head;
|
|
1914 rep_p->cursession->sent_cmdlist.num = rep_p->cursession->new_cmdlist.num;
|
|
1915
|
|
1916 rep_p->cursession->new_cmdlist.head = NULL;
|
|
1917 rep_p->cursession->new_cmdlist.num = 0;
|
|
1918
|
|
1919 return;
|
|
1920 }
|
|
1921
|
|
1922 static int
|
|
1923 rep_send_cmds(fd,cmdlist)
|
|
1924 int fd;
|
|
1925 rep_cmdlist *cmdlist;
|
|
1926 {
|
|
1927 rep_cmd *cur;
|
|
1928 unsigned int nlen;
|
|
1929
|
|
1930 if ((fd<0) || (cmdlist == NULL)) {
|
|
1931 return(FALSE);
|
|
1932 }
|
|
1933
|
|
1934 if ((cmdlist->head == NULL) || (cmdlist->num == 0)) {
|
|
1935 return(TRUE);
|
|
1936 }
|
|
1937
|
|
1938 for (cur = cmdlist->head; cur; cur = cur->next) {
|
|
1939 if (writen(fd, cur->pkt, cur->len+REP_HEADER_SIZE) < 0) {
|
|
1940 return(FALSE);
|
|
1941 }
|
|
1942 }
|
|
1943 return(TRUE);
|
|
1944 }
|
|
1945
|
|
1946 /*
|
|
1947 static int
|
|
1948 session_fd_check(sn, rfds_p, efds_p)
|
|
1949 Session *sn;
|
|
1950 fd_set *rfds_p;
|
|
1951 fd_set *efds_p;
|
|
1952 {
|
|
1953 rep_cmdlist smcmdlist = {NULL,0};
|
|
1954 rep_cmdlist txtcmdlist = {NULL,0};
|
|
1955
|
|
1956 if (sn == NULL) return FALSE;
|
|
1957
|
|
1958 if (sn->smfd > 0) {
|
|
1959 if (FD_ISSET(sn->smfd, efds_p)) {
|
|
1960 if (sn->rfd != sn->sfd) close(sn->rfd);
|
|
1961 sn->rfd = -1;
|
|
1962 // 再接続処理をしたい
|
|
1963 return FALSE;
|
|
1964 } else if (FD_ISSET(sn->rfd, rfds_p)) {
|
|
1965 if (rep_recv_cmds(sn->rfd, &(smcmdlist), &(txtcmdlist)) == FALSE) {
|
|
1966 if (sn->rfd != sn->sfd) close(sn->rfd);
|
|
1967 sn->rfd = -1;
|
|
1968 return(FALSE);
|
|
1969 }
|
|
1970
|
|
1971 if ((cmdlist.head) && (cmdlist.head->uid == 99)) { // 単方向コマンド
|
|
1972 rep_exe_cmdlist(sn, sn->rfd, &(cmdlist));
|
|
1973 free_cmdlist(&(cmdlist));
|
|
1974 } else if ((cmdlist.head) && (cmdlist.head->uid == sn->uid)) { // 自分のコマンド
|
|
1975 free_cmdlist(&cmdlist);
|
|
1976
|
|
1977 if (rep_send_cmds(sn->sfd, &(sn->new_cmdlist)) == FALSE) {
|
|
1978 if (sn->rfd != sn->sfd) close(sn->sfd);
|
|
1979 sn->sfd = -1;
|
|
1980 return FALSE;
|
|
1981 }
|
|
1982
|
|
1983 sn->sent_cmdlist.head = sn->new_cmdlist.head;
|
|
1984 sn->sent_cmdlist.num = sn->new_cmdlist.num;
|
|
1985 sn->new_cmdlist.head = NULL;
|
|
1986 sn->new_cmdlist.num = 0;
|
|
1987
|
|
1988 } else { // リングに流すコマンド
|
|
1989 // 受け取ったトークンとユーザからのREPコマンドを比較・マージする
|
|
1990 // 既に送信した REPコマンド列 と比較
|
|
1991 translate(&(sn->sent_cmdlist), &(cmdlist));
|
|
1992 del_ignored_cmd(&(cmdlist));
|
|
1993 set_header_to_pkt(&(cmdlist));
|
|
1994
|
|
1995 if (rep_send_cmds(sn->sfd, &(cmdlist)) == FALSE) {
|
|
1996 if (sn->rfd != sn->sfd) close(sn->sfd);
|
|
1997 sn->sfd = -1;
|
|
1998 free_cmdlist(&(cmdlist));
|
|
1999 return FALSE;
|
|
2000 }
|
|
2001
|
|
2002 // 新規に追加された REPコマンド列 との比較
|
|
2003 translate(&(sn->new_cmdlist), &(cmdlist));
|
|
2004 del_ignored_cmd(&(cmdlist));
|
|
2005 set_header_to_pkt(&(sn->new_cmdlist));
|
|
2006
|
|
2007 // 変換したトークンREPコマンドを自分のバッファに反映する。
|
|
2008 //各パケットにはその変換は反映されていない.
|
|
2009 rep_exe_cmdlist(sn, sn->rfd, &(cmdlist));
|
|
2010
|
|
2011 free_cmdlist(&(cmdlist));
|
|
2012 }
|
|
2013 }
|
|
2014 }
|
|
2015 if (sn->sfd > 0) {
|
|
2016 if (FD_ISSET(sn->sfd, efds_p)) {
|
|
2017 if (sn->rfd != sn->sfd) close(sn->sfd);
|
|
2018 sn->sfd = -1;
|
|
2019 // 再接続処理をしたい
|
|
2020 return FALSE;
|
|
2021 } else if (FD_ISSET(sn->sfd, rfds_p)) { // from send client
|
|
2022 if (rep_recv_cmds(sn->sfd, &cmdlist) == FALSE) {
|
|
2023 if (sn->rfd != sn->sfd) close(sn->sfd);
|
|
2024 sn->sfd = -1;
|
|
2025 return(FALSE);
|
|
2026 }
|
|
2027 rep_exe_cmdlist(sn, sn->sfd, &cmdlist);
|
|
2028 free_cmdlist(&cmdlist);
|
|
2029 }
|
|
2030 }
|
|
2031 }
|
|
2032
|
|
2033 */
|
|
2034
|
|
2035 int
|
|
2036 rep_fd_check(fd, rfds_p, efds_p)
|
|
2037 int fd; // input from keyboard or something...
|
|
2038 fd_set *rfds_p; // readable fds
|
|
2039 fd_set *efds_p; // include a error fd
|
|
2040 {
|
|
2041 int newfd;
|
|
2042 rep_T *rep_p;
|
|
2043 rep_cmdlist smcmdlist = {NULL,0};
|
|
2044 rep_cmdlist txtcmdlist = {NULL,0};
|
|
2045
|
|
2046 Session *sn;
|
|
2047
|
|
2048 /* input from keyboard is most important.
|
|
2049 * reditor has nothing to do */
|
|
2050 if (FD_ISSET(fd, rfds_p) || FD_ISSET(fd, efds_p)) {
|
|
2051 return(TRUE);
|
|
2052 }
|
|
2053
|
|
2054 rep_p = get_rep();
|
|
2055
|
|
2056 if ((rep_p->smfd > 0) && (FD_ISSET(rep_p->smfd, rfds_p))) {
|
|
2057 /* we don't need this?
|
|
2058 // 受け取ったトークンとユーザからのREPコマンドを比較・マージする
|
|
2059 // 既に送信した REPコマンド列 と比較
|
|
2060 translate(&(sn->sent_cmdlist), &(cmdlist));
|
|
2061 del_ignored_cmd(&(cmdlist));
|
|
2062 set_header_to_pkt(&(cmdlist));
|
|
2063 */
|
|
2064
|
|
2065 if (rep_recv_cmds(rep_p->smfd, &(smcmdlist), &(txtcmdlist)) == FALSE) {
|
|
2066 close(rep_p->smfd);
|
|
2067 rep_p->smfd = -1;
|
|
2068 return FALSE;
|
|
2069 }
|
|
2070 /* Session ごとに行う↓*/
|
12
|
2071 /*
|
8
|
2072 for(sn = rep_p->shead; sn ; sn = sn->next) {
|
|
2073 translate( &sn->new_cmdlist , &txtcmdlist);
|
|
2074 }
|
12
|
2075 */
|
8
|
2076 del_ignored_cmd(&txtcmdlist);
|
|
2077 rep_exe_pktlist(&txtcmdlist);
|
|
2078
|
|
2079 if (rep_send_cmds(rep_p->smfd, &(txtcmdlist)) == FALSE) {
|
|
2080 close(sn->smfd);
|
|
2081 sn->smfd = -1;
|
|
2082 free_cmdlist(&(txtcmdlist));
|
|
2083 return FALSE;
|
|
2084 }
|
|
2085 free_cmdlist(&(txtcmdlist));
|
|
2086
|
|
2087 rep_exe_pktlist( &smcmdlist);
|
|
2088 free_cmdlist(&(smcmdlist));
|
|
2089
|
|
2090 return TRUE;
|
|
2091 }
|
|
2092 rep_exe_pktlist( &smcmdlist);
|
|
2093 free_cmdlist(&(smcmdlist));
|
|
2094
|
|
2095 /*
|
|
2096 session_fd_check(rep_p->slineup, rfds_p, efds_p);
|
|
2097
|
|
2098 for (sn=rep_p->shead; sn; sn=sn->next) {
|
|
2099 session_fd_check(sn, rfds_p, efds_p);
|
|
2100 }
|
|
2101 */
|
|
2102
|
|
2103 }
|
|
2104
|
|
2105 /*
|
|
2106 static int
|
|
2107 session_fd_set(sn, rfds_p, efds_p, max_fds)
|
|
2108 Session *sn;
|
|
2109 fd_set *rfds_p;
|
|
2110 fd_set *efds_p;
|
|
2111 int max_fds;
|
|
2112 {
|
|
2113 if (sn == NULL) return max_fds;
|
|
2114
|
|
2115 if (sn->rfd > 0) {
|
|
2116 FD_SET(sn->rfd, rfds_p);
|
|
2117 FD_SET(sn->rfd, efds_p);
|
|
2118 if (max_fds < sn->rfd) {
|
|
2119 max_fds = sn->rfd;
|
|
2120 }
|
|
2121 }
|
|
2122 if (sn->sfd > 0) {
|
|
2123 FD_SET(sn->sfd, rfds_p);
|
|
2124 FD_SET(sn->sfd, efds_p);
|
|
2125 if (max_fds < sn->sfd) {
|
|
2126 max_fds = sn->sfd;
|
|
2127 }
|
|
2128 }
|
|
2129 return max_fds;
|
|
2130 }
|
|
2131 */
|
|
2132
|
|
2133
|
|
2134 int
|
|
2135 rep_fd_set(rfds_p, efds_p, max_fds)
|
|
2136 fd_set *rfds_p;
|
|
2137 fd_set *efds_p;
|
|
2138 int max_fds;
|
|
2139 {
|
|
2140 rep_T *rep_p;
|
|
2141 Session *sn;
|
|
2142 int i;
|
|
2143
|
|
2144 rep_p = get_rep();
|
|
2145
|
|
2146 if (rep_p->smfd > 0) {
|
|
2147 FD_SET(rep_p->smfd,rfds_p);
|
|
2148 FD_SET(rep_p->smfd,efds_p);
|
|
2149 if(max_fds < rep_p->smfd){
|
|
2150 max_fds = rep_p->smfd;
|
|
2151 }
|
|
2152 }
|
|
2153
|
|
2154 /*
|
|
2155 max_fds = session_fd_set(rep_p->slineup, rfds_p, efds_p, max_fds);
|
|
2156
|
|
2157 for (sn=rep_p->shead; sn; sn=sn->next) {
|
|
2158 max_fds = session_fd_set(sn, rfds_p, efds_p, max_fds);
|
|
2159 }
|
|
2160 */
|
|
2161
|
|
2162 return(max_fds);
|
|
2163 }
|
|
2164
|
|
2165
|
|
2166
|
|
2167 /*
|
|
2168 * read などで待つ場合に、この関数で REP 関連のデータをチェックする
|
|
2169 * 指定した fd ( read で読みこむ) から入力があるとぬける。
|
|
2170 */
|
|
2171 int
|
|
2172 rep_select(fd)
|
|
2173 int fd;
|
|
2174 {
|
|
2175 fd_set rfds_p;
|
|
2176 fd_set efds_p;
|
|
2177 int sk;
|
|
2178 int max_fds = MAX_FDS;
|
|
2179
|
|
2180 struct timeval tv;
|
|
2181
|
|
2182 if (fd < 0) return(FALSE);
|
|
2183
|
|
2184 while (1) {
|
|
2185 /* select の中で modify されてるので、初期化 */
|
|
2186 tv.tv_sec = 0;
|
|
2187 tv.tv_usec = 100000;
|
|
2188 FD_ZERO(&rfds_p);
|
|
2189 FD_ZERO(&efds_p);
|
|
2190
|
|
2191 FD_SET(fd,&rfds_p);
|
|
2192
|
|
2193 max_fds = rep_fd_set(&rfds_p, &efds_p, max_fds);
|
|
2194
|
|
2195 if ((sk = select(max_fds+1, &rfds_p, NULL, &efds_p, &tv)) < 0) {
|
|
2196 e_msg_wrp("rep_select(): ERROR");
|
|
2197 return(FALSE);
|
|
2198 }
|
|
2199
|
|
2200 rep_fd_check(fd, &rfds_p, &efds_p);
|
|
2201 return(TRUE);
|
|
2202 }
|
|
2203 }
|
|
2204
|
|
2205 void
|
|
2206 rep_end()
|
|
2207 {
|
|
2208 rep_T *rep_p;
|
|
2209 rep_p = get_rep();
|
|
2210
|
|
2211 if (rep_p->shead) free_session_list(rep_p->shead); // cursession is freed
|
|
2212 if (rep_p->slineup) free_session(rep_p->slineup);
|
|
2213 if (rep_p->servername) free_wrp(rep_p->servername);
|
|
2214 if (rep_p->smfd > 0) close(rep_p->smfd);
|
|
2215
|
|
2216 set_curbuf_wrp(rep_p->scratch_buf);
|
|
2217
|
|
2218 rep_init();
|
|
2219 }
|
|
2220
|
|
2221
|
|
2222 /* append newline separated text to session buf */
|
|
2223 static int
|
|
2224 append_newline_sep_text(sn, text)
|
|
2225 Session *sn;
|
|
2226 char *text;
|
|
2227 {
|
|
2228 char *str;
|
|
2229 char *cur;
|
|
2230 // BUFTYPE *oldbuf;
|
|
2231 Session *oldsn;
|
|
2232
|
|
2233 /*
|
|
2234 *"append_memline()" is available "curbuf" only
|
|
2235 * thus, we must set buffer to "curbuf"
|
|
2236 */
|
|
2237 oldsn = set_cursession(sn);
|
|
2238
|
|
2239 for (str = cur = text; cur && *cur ; str = cur) {
|
|
2240 cur = strchr(str, '\n');
|
|
2241 if (cur) {
|
|
2242 *cur = '\0';
|
|
2243 cur++;
|
|
2244 }
|
|
2245
|
|
2246 append_memline_wrp(1, str);
|
|
2247 }
|
|
2248
|
|
2249 set_cursession(oldsn);
|
|
2250
|
|
2251 return TRUE;
|
|
2252 }
|
|
2253
|
|
2254 /* return value (file name) is allocated */
|
|
2255 static char *
|
|
2256 get_sname_by_snum(snum)
|
|
2257 int snum;
|
|
2258 {
|
|
2259 char *tmp, *text, *sname;
|
|
2260 int i, len;
|
|
2261 int maxlnum;
|
|
2262 rep_T *rep = get_rep();
|
|
2263
|
|
2264 maxlnum = get_bufmaxline_wrp(rep->slineup->buf);
|
|
2265
|
|
2266 for (i = 1; i <= maxlnum; i++) {
|
|
2267 // text is "filename:hostname:sessionnumber"
|
|
2268 text = get_memline_wrp(rep->slineup->buf, i);
|
|
2269
|
|
2270
|
|
2271 // get ':' separated last parameter (session number)
|
|
2272 if ((tmp = strrchr(text, ':')) == NULL) {
|
|
2273 return NULL;
|
|
2274 }
|
|
2275 tmp++;
|
|
2276
|
|
2277 if (snum == atol(tmp)) {
|
|
2278 // get ':' separated first parameter (filename)
|
|
2279 tmp = strchr(text, ':');
|
|
2280 len = tmp - text;
|
|
2281 if ((sname = (char *)rep_alloc(len+1)) == NULL){
|
|
2282 e_msg_wrp("no memory!");
|
|
2283 return NULL;
|
|
2284 }
|
|
2285 memcpy(sname, text, len);
|
|
2286 sname[len] = '\0';
|
|
2287 return sname;
|
|
2288 }
|
|
2289 }
|
|
2290
|
|
2291 return NULL;
|
|
2292
|
|
2293 }
|