/*////////////////////////////////////////////////////////////////////////
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 <ysato@etl.go.jp>
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 <signal.h>
#include <ctype.h>
#include <stdio.h>
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
syntax highlighted by Code2HTML, v. 0.9.1