/*//////////////////////////////////////////////////////////////////////// Copyright (c) 1993 Electrotechnical Laboratry (ETL) Permission to use, copy, modify, and distribute this material for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and that the name of ETL not be used in advertising or publicity pertaining to this material without the specific, prior written permission of an authorized representative of ETL. ETL MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. ///////////////////////////////////////////////////////////////////////// Content-Type: program/C; charset=US-ASCII Program: onew.c (onew server) Author: Yutaka Sato Status: public Description: History: ancient created =V2.0 930730 return kakutei keys if the buffers don't include non-ascii =V2.0 930730 Control-U clears current input buffer if it's not empty ///////////////////////////////////////////////////////////////////////*/ #include #include #include extern char *getenv(); #include "onew.h" int on_via; int onew_client_version = 1; #define VER1 (onew_client_version == 1) #define VER2 (onew_client_version == 2) int ONEW_THRUSYMS_ON; static Linebuff onew_buf; static Mssgbuff onew_out; static int idbx; static clear_bufs(){ onew_buf[0] = 0; onew_out[0] = 0; idbx = 0; } static int is_tty; static int is_sock; static FILE *logfp; static put_client(); /*######################################################################* * ONEW AS A ROMAJI/KANA/KANJI HENKAN SERVER PROCESS * *######################################################################*/ static cdump(name) char *name; { int ch; int count,bytes; printf("unsigned char %s[] = {\n",name); count = 0; bytes = 0; while( (ch = getchar()) != EOF ){ bytes++; printf("%3d,",ch); if( 20 <= ++count ){ printf("\n"); count = 0; } } printf("};\n"); printf("int %s_SIZE = %d;\n",name,bytes); } main(ac,av) char *av[]; { char *debug; int ch1,ch2; if( 2 <= ac ){ if( strcmp(av[1],"-rktab") == 0 ){ Onew_showrktab(); exit(0); } if( strcmp(av[1],"-cdump") == 0 ){ cdump(av[2]); exit(0); } if( strcmp(av[1],"-xrktab") == 0 ){ Onew_extract_rktabs(); exit(0); } if( strcmp(av[1],"-kkdic") == 0 ){ Onew_kkdic(); exit(0); } } ac = onew_on_via(ac,av); if( isatty(0) ){ Onew_ttyIcanon(0); logfp = stderr; }else{ Onew_notty(); logfp = stdout; } is_tty = !on_via && isatty(1); signal(SIGINT,SIG_IGN); ONEW_MESSAGE(0,"[ROMKAN & KANAKAN FILTER] %s start.",Onew_version()); if( debug = getenv("DEBUG_onew") ) ONEW_DEBUG = atoi(debug); /* keep Cntl('K') uninterpreted */ ONEW_KANA_TOGGLE = Cntl('Z'); for(;;){ ch1 = kgetc(); if(ch1 == 0) continue; if( ch1 == 0xFF || ch1 == -1 ) break; if( is_sock ){ put_client(S_CHATTR,"+U"); if( ch1 & 0x80 ){ ch2 = kgetc(); put_client(S_INPUT,"%c%c",ch1,ch2); }else put_client(S_INPUT,"%c",ch1); put_client(S_CHATTR,"-U"); }else if( is_tty ){ if( ch1 & 0x80 ){ ch2 = kgetc(); Onew_fprintf(logfp,"%c%c",ch1,ch2); }else{ fprintf(logfp,"%c",ch1); } }else { printf("%c",ch1); if( ch1 & 0x80 ){ ch2 = kgetc(); printf("%c",ch2); } } fflush(logfp); } if( isatty(0) ) Onew_ttyIcanon(1); if( !is_tty && !is_sock ) printf("\n"); Onew_KK_freqsave(); } static onew_xcom(){ int ch; Onew_fprintf(stderr,"ONEW-COMMAND> "); ch = getchar(); Onew_fprintf(stderr,"%c\n",ch); } ONEW_GETCHAR() { int ch; for(;;){ ch = GetChar1(); ouiTrace("onew_GETCHAR","(%x)",ch); if( ONEW_DEBUG ) Onew_fprintf(stderr,"ONEW_GETCHAR: %x\n",ch); switch( ch ){ default: if( ch == Cntl('\\') ) ch = Cntl('@'); goto Break; case CC_SYNC: set_is_sock(); put_client(S_SYNC,""); ch = 0; break; case CC_COMMAND: set_is_sock(); switch( GetChar1() ){ case CCC_VERSION2: onew_client_version = 2; break; case CCC_SYM_JIS: ONEW_THRUSYMS_ON = 0; break; case CCC_SYM_ASCII: ONEW_THRUSYMS_ON = 1; break; } break; case CC_XCOMMAND: set_is_sock(); onew_xcom(); break; } } Break:; return ch; } static put_client(command,form,a,b,c,d,e,f) char *command,*form; { Linebuff out,tmp; char *op; int ci,ch1,ch2; static int nmsg = 0; if( nmsg++ == 1 ) put_client(S_MESSAGE,":[ROMKAN & KANAKAN FILTEDR] %s", Onew_version()); op = (char*)out; sprintf(op,"%c%s",0xFF,command); op += strlen(op); sprintf(op,form,a,b,c,d,e,f); if( strcmp(command,S_INPUT) == 0 ) if( VER1 ) /* AND 1bytes character is INHIBITED */ { ASCII_TO_JIS(op,tmp); strcpy(op,tmp); } op += strlen(op); sprintf(op,"%c",0xFF); if( ONEW_DEBUG ){ fprintf(stderr,"%s: %-10s %8x %8x ",command,form,a,b,c,d,e,f); for( ci = 0; ch1 = out[ci]; ci++ ){ ch2 = out[ci+1]; if( ch1 & 0x80 && ch2 & 0x80 ){ fprintf(stderr,"\033$B%c%c\033(B",ch1&0x7F,ch2&0x7F); ci++; }else fprintf(stderr,"[%2x]",ch1); } fprintf(stderr,"\n"); } send_to_client(out); } static got_server(ch){ if( ch == 0xFF ){ /* do echo */ ch = 0; } return ch; } static charlen(str) char *str; { int i,len,ch; len = 0; for( i = 0; ch = str[i]; i++ ){ len++; if( (ch & 0x80) && str[i+1] ) i++; } return len; } static int romkan_init_done; kgetc(){ int inch; if( romkan_init_done == 0 ){ romkan_init_done = 1; Onew_RK_init(); Onew_RK_cmode_set('h'); } inch = Onew_romkan(); if( inch == ESC_CH ) if( is_tty ){ if( OnewPeekchar(200) == EOF ) inch = EOF; } if( inch == 0 ){}else if( inch == -1 ){ /*fprintf(stderr,"*** EOF ***\n");*/ }else if( idbx ){ switch( inch ){ case 033: case Cntl('C'): case '\n': case '\r': idbx = 0; if( Onew_non_ascii(onew_buf) ){ inch = 0; } break; case 0x7F: case '\b': if( 0 < idbx ){ if( onew_buf[idbx-1] & 0x80 ) idbx -= 2; else idbx -= 1; onew_buf[idbx] = 0; }else ONEW_BEEP(1); break; case Cntl('U'): if( is_tty ) Onew_fprintf(stderr,"\r"); else if( is_sock ){ put_client(S_DELETE,"%d %d", strlen(onew_buf),charlen(onew_buf)); put_client(S_INPUT,"%s","");/* do delete */ } clear_bufs(); inch = 0; break; case Cntl('V'): inch = Onew_romkan(); onew_buf[idbx++] = inch; break; default: if( 0x20 < inch && inch < 0x7F || inch & 0x80 ) onew_buf[idbx++] = inch; else if( Onew_RK_imode() ){ ONEW_MESSAGE(1,"[%x] %s", inch,"ONEW BUFFER IS NOT EMPTY."); ONEW_BEEP(2); sleep(2); inch = 0; }else onew_buf[idbx++] = inch; break; } }else{ if( Onew_RK_imode() ){ if( 0x20 < inch && inch < 0x7F || inch & 0x80 ){ onew_buf[idbx++] = inch; } }else{ /* 920923 */ if( !iscntrl(inch) ) onew_buf[idbx++] = inch; } } onew_buf[idbx] = 0; return inch; } ONEW_KANAKAN(ch){ char com; if( idbx ){ if( is_sock ){ put_client(S_DELETE,"%d %d", strlen(onew_buf),charlen(onew_buf)); } com = Onew_kanakan(ch,onew_buf,0,idbx); switch( com ){ case Cntl('H'): case 0x7F: strcpy(onew_out,onew_buf); if( is_sock ){ put_client(S_CHATTR,"%s","+U"); put_client(S_INPUT,"%s",onew_out); put_client(S_CHATTR,"%s","-U"); } break; default: /* ONEW_KAKUTEI(com); */ Onew_kakutei(com); break; } com = 0; }else{ com = ch; } return com; } /* * returns TRUE if kakutei key should NOT be treated as normal input */ static pending_newline; ONEW_KAKUTEI(key){ int na; na = Onew_non_ascii(onew_buf) || Onew_non_ascii(onew_out); if( is_sock ){ put_client(S_CONFIRM,""); }else if( is_tty ){ if( onew_out[0] ){ Onew_fprintf(stdout,"%s\n",onew_out); fflush(stdout); pending_newline = 0; } }else{ printf("\n%s",onew_out); } clear_bufs(); return na; } static int LAST_KH; ONEW_DISP_KANAHALF(ch){ if( is_sock ){ if( ch == ' ' ){ put_client(S_INPUT,"%s",""); }else{ put_client(S_INPUT,"%c%c",0x80|'#',0x80|ch); put_client(S_DELETE,"%d %d",2,1); } }else if( is_tty ){ printf("%c\b",ch); fflush(stdout); } LAST_KH = ch; } set_is_sock(){ if( is_sock == 0 ){ is_sock = 1; if( LAST_KH ) ONEW_DISP_KANAHALF(LAST_KH); } } ONEW_DISP_KANAKANB(so,left,current,right) char *left,*current,*right; { int bytes,chars; if( is_sock ){ bytes = strlen(left) + strlen(current) + strlen(right); chars =charlen(left) +charlen(current) +charlen(right); if( *left ){ put_client(S_CHATTR,"%s","+U"); put_client(S_INPUT,"%s",left); put_client(S_CHATTR,"%s","-U"); } if( *current ){ put_client(S_CHATTR,"%s","+R"); put_client(S_INPUT,"%s",current); put_client(S_CHATTR,"%s","-R"); } if( *right ){ put_client(S_CHATTR,"%s","+U"); put_client(S_INPUT,"%s",right); put_client(S_CHATTR,"%s","-U"); } put_client(S_DELETE,"%d %d",bytes,chars); if( VER1 ) put_client(S_MESSAGE,"%s%s%s%s%s", left,"\033[7m",current,"\033[m",right); }else if( is_tty ){ Onew_fprintf(stderr,"\r%s%s%s%s%s", left,"\033[7m",current,"\033[m",right); Onew_fprintf(stderr,"\033[K\r"); pending_newline = 1; fflush(stderr); } sprintf(onew_out,"%s%s%s",left,current,right); onew_out[strlen(onew_out)+1] = 0; } ONEW_BEEP(nsec){ Onew_fprintf(stderr,"%c",7); fflush(stdout); } static int prev_modef; ONEW_DISP_ROMKANMODE(cmode,chelp,modef) char *cmode,*chelp; { if( modef == prev_modef ) return; if( is_sock ){ if( VER2 ) put_client(S_RKSTAT,"%s %s %s",cmode,chelp,Onew_version()); else put_client(S_MESSAGE,"%s%s",cmode,chelp); }else if( is_tty ){ if( pending_newline ) Onew_fprintf(stderr,"\n"); Onew_fprintf(stderr,"%s %s\n",cmode,chelp); } prev_modef = modef; } ONEW_MESSAGE(so,form,a,b,c,d) char *form; char *a,*b,*c,*d; { Mssgbuff msg; static int nmsg = 0; if( is_tty ){ if( nmsg == 0 ) Onew_fprintf(stderr,"Hit ESC to quit.\n"); Onew_fprintf(stderr,"\r"); if( so )Onew_fprintf(stderr,"\n\033[7m"); Onew_fprintf(stderr,form,a,b,c,d); if( so )Onew_fprintf(stderr,"\033[m"); Onew_fprintf(stderr,"\n"); }else if( is_sock ) { sprintf(msg,form,a,b,c,d); put_client(S_MESSAGE,":%s",msg); } nmsg++; } int TERMCAP_INIT = 1; Tgetnum(id) char *id; { if(strcmp(id,"li") == 0) return 24; else return 80; } #ifndef VIA onew_on_via(ac,av){ return ac; } GetChar1(){ int ch; ch = Onew_getchar(0,0); return ch; } send_to_client(out){ printf("%s",out); fflush(stdout); } #else #include "via+onew.c" #endif