// Outputs to the file. Return value: 0 = ok, -1 = error. int iso2utf8_file(FILE *fp, char *ascii, int userdatalength) { int result = 0; int idx; unsigned int c; char tmp[10]; int len; char logtmp[51]; int i; if (!fp || userdatalength < 0) return -1; #ifdef DEBUGMSG log_charconv = 1; #endif if (log_charconv) { *logch_buffer = 0; logch("!! iso2utf8_file(..., userdatalength=%i)", userdatalength); logch(NULL); } for (idx = 0; idx < userdatalength; idx++) { len = 0; c = ascii[idx] & 0xFF; // Euro character is 20AC in UTF-8, but A4 in ISO-8859-15: if (c == 0xA4) c = 0x20AC; if (c <= 0x7F) tmp[len++] = (char)c; else if (c <= 0x7FF) { tmp[len++] = (char)( 0xC0 | ((c >> 6) & 0x1F) ); tmp[len++] = (char)( 0x80 | (c & 0x3F) ); } else if (c <= 0x7FFF) // or <= 0xFFFF ?
int sbbs_t::exec(csi_t *csi) { char str[256],*path; char tmp[512]; uchar buf[1025],ch; int i,j,file; long l; FILE *stream; if(usrgrps) cursubnum=usrsub[curgrp][cursub[curgrp]]; /* Used for ARS */ else cursubnum=INVALID_SUB; if(usrlibs) { curdirnum=usrdir[curlib][curdir[curlib]]; /* Used for ARS */ path=cfg.dir[usrdir[curlib][curdir[curlib]]]->path; } else { curdirnum=INVALID_DIR; path=nulstr; } now=time(NULL); if(csi->ip>=csi->cs+csi->length) return(1); if(*csi->ip>=CS_FUNCTIONS) return(exec_function(csi)); /**********************************************/ /* Miscellaneous variable length instructions */ /**********************************************/ if(*csi->ip>=CS_MISC) return(exec_misc(csi,path)); /********************************/ /* ASCIIZ argument instructions */ /********************************/ if(*csi->ip>=CS_ASCIIZ) { switch(*(csi->ip++)) { case CS_STR_FUNCTION: switch(*(csi->ip++)) { case CS_LOGIN: csi->logic=login(csi->str,(char*)csi->ip); break; case CS_LOAD_TEXT: csi->logic=LOGIC_FALSE; for(i=0;i<TOTAL_TEXT;i++) if(text[i]!=text_sav[i]) { if(text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; } SAFEPRINTF2(str,"%s%s.dat" ,cfg.ctrl_dir,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); if((stream=fnopen(&file,str,O_RDONLY))==NULL) { errormsg(WHERE,ERR_OPEN,str,O_RDONLY); break; } for(i=0;i<TOTAL_TEXT && !feof(stream);i++) { if((text[i]=readtext((long *)NULL,stream,i))==NULL) { i--; continue; } if(!strcmp(text[i],text_sav[i])) { /* If identical */ free(text[i]); /* Don't alloc */ text[i]=text_sav[i]; } else if(text[i][0]==0) { free(text[i]); text[i]=nulstr; } } if(i<TOTAL_TEXT) { fclose(stream); errormsg(WHERE,ERR_READ,str,TOTAL_TEXT); break; } fclose(stream); csi->logic=LOGIC_TRUE; break; default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); break; } while(*(csi->ip++)); /* Find NULL */ return(0); case CS_LOG: log(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_GETCMD: csi->cmd=(uchar)getkeys((char*)csi->ip,0); if((char)csi->cmd==-1) csi->cmd=3; break; case CS_CMDSTR: if(stricmp(csi->str,(char*)csi->ip)) { while(*(csi->ip++)); /* Find NULL */ skipto(csi,CS_END_CMD); csi->ip++; return(0); } break; case CS_CMDKEYS: for(i=0;csi->ip[i];i++) if(csi->cmd==csi->ip[i]) break; if(!csi->ip[i]) { while(*(csi->ip++)); /* Find NULL */ skipto(csi,CS_END_CMD); csi->ip++; return(0); } break; case CS_GET_TEMPLATE: gettmplt(csi->str,(char*)csi->ip,K_LINE); if(sys_status&SS_ABORT) csi->str[0]=0; csi->cmd=csi->str[0]; break; case CS_TRASHCAN: csi->logic=!trashcan(csi->str,(char*)csi->ip); break; case CS_CREATE_SIF: create_sif_dat((char*)csi->ip,csi->str); break; case CS_READ_SIF: read_sif_dat((char*)csi->ip,csi->str); break; case CS_MNEMONICS: mnemonics((char*)csi->ip); break; case CS_PRINT: putmsg(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR|P_NOABORT); break; case CS_PRINT_LOCAL: if(online==ON_LOCAL) eprintf(LOG_INFO,"%s",cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); else lputs(LOG_INFO,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_PRINT_REMOTE: putcom(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_PRINTFILE: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); break; case CS_PRINTFILE_REMOTE: if(online!=ON_REMOTE || !(console&CON_R_ECHO)) break; console&=~CON_L_ECHO; printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); console|=CON_L_ECHO; break; case CS_PRINTFILE_LOCAL: if(!(console&CON_L_ECHO)) break; console&=~CON_R_ECHO; printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR); console|=CON_R_ECHO; break; case CS_CHKFILE: csi->logic=!fexistcase(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_EXEC: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),0); break; case CS_EXEC_INT: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),EX_STDIO); break; case CS_EXEC_XTRN: for(i=0;i<cfg.total_xtrns;i++) if(!stricmp(cfg.xtrn[i]->code,(char*)csi->ip)) break; if(i<cfg.total_xtrns) exec_xtrn(i); break; case CS_EXEC_BIN: exec_bin(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),csi,/* startup_dir: */NULL); break; case CS_YES_NO: csi->logic=!yesno(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_NO_YES: csi->logic=!noyes(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_MENU: menu(cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_SETSTR: strcpy(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_SET_MENU_DIR: cmdstr((char*)csi->ip,path,csi->str,menu_dir); break; case CS_SET_MENU_FILE: cmdstr((char*)csi->ip,path,csi->str,menu_file); break; case CS_COMPARE_STR: csi->logic=stricmp(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf)); break; case CS_COMPARE_KEYS: for(i=0;csi->ip[i];i++) if(csi->cmd==csi->ip[i]) break; if(csi->ip[i]) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; break; case CS_COMPARE_WORD: csi->logic=strnicmp(csi->str,(char*)csi->ip,strlen((char*)csi->ip)); break; default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); break; } while(*(csi->ip++)); /* Find NULL */ return(0); } if(*csi->ip>=CS_THREE_BYTE) { switch(*(csi->ip++)) { case CS_THREE_MORE_BYTES: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); case CS_GOTO: csi->ip=csi->cs+*((ushort *)(csi->ip)); return(0); case CS_CALL: if(csi->rets<MAX_RETS) { csi->ret[csi->rets++]=csi->ip+2; csi->ip=csi->cs+*((ushort *)(csi->ip)); } return(0); case CS_MSWAIT: mswait(*(ushort *)csi->ip); csi->ip+=2; return(0); case CS_TOGGLE_NODE_MISC: if(getnodedat(cfg.node_num,&thisnode,true)==0) { thisnode.misc^=*(ushort *)csi->ip; putnodedat(cfg.node_num,&thisnode); } csi->ip+=2; return(0); case CS_COMPARE_NODE_MISC: getnodedat(cfg.node_num,&thisnode,0); if((thisnode.misc&*(ushort *)csi->ip)==*(ushort *)csi->ip) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; csi->ip+=2; return(0); case CS_ADJUST_USER_CREDITS: i=*(short *)csi->ip; l=i*1024L; if(l<0) subtract_cdt(&cfg,&useron,-l); else useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,l); csi->ip+=2; return(0); case CS_ADJUST_USER_MINUTES: i=*(short *)csi->ip; useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,i); csi->ip+=2; return(0); case CS_GETNUM: i=*(short *)csi->ip; csi->ip+=2; l=getnum(i); if(l<=0) { csi->str[0]=0; csi->logic=LOGIC_FALSE; } else { sprintf(csi->str,"%lu",l); csi->logic=LOGIC_TRUE; } return(0); case CS_TOGGLE_USER_FLAG: i=*(csi->ip++); ch=*(csi->ip++); switch(i) { case '1': useron.flags1^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS1,8 ,ultoa(useron.flags1,tmp,16)); break; case '2': useron.flags2^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS2,8 ,ultoa(useron.flags2,tmp,16)); break; case '3': useron.flags3^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS3,8 ,ultoa(useron.flags3,tmp,16)); break; case '4': useron.flags4^=FLAG(ch); putuserrec(&cfg,useron.number,U_FLAGS4,8 ,ultoa(useron.flags4,tmp,16)); break; case 'R': useron.rest^=FLAG(ch); putuserrec(&cfg,useron.number,U_REST,8 ,ultoa(useron.rest,tmp,16)); break; case 'E': useron.exempt^=FLAG(ch); putuserrec(&cfg,useron.number,U_EXEMPT,8 ,ultoa(useron.exempt,tmp,16)); break; default: errormsg(WHERE,ERR_CHK,"user flag type",*(csi->ip-2)); return(0); } return(0); case CS_REVERT_TEXT: i=*(ushort *)csi->ip; csi->ip+=2; if((ushort)i==0xffff) { for(i=0;i<TOTAL_TEXT;i++) { if(text[i]!=text_sav[i] && text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; } return(0); } i--; if(i>=TOTAL_TEXT) { errormsg(WHERE,ERR_CHK,"revert text #",i); return(0); } if(text[i]!=text_sav[i] && text[i]!=nulstr) free(text[i]); text[i]=text_sav[i]; return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } } if(*csi->ip>=CS_TWO_BYTE) { switch(*(csi->ip++)) { case CS_TWO_MORE_BYTES: switch(*(csi->ip++)) { case CS_USER_EVENT: user_event((user_event_t)*(csi->ip++)); return(0); } errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); case CS_SETLOGIC: csi->logic=*csi->ip++; return(0); case CS_CMDKEY: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd)) || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80 && isdigit(csi->cmd&0x7f))) { csi->ip++; return(0); } if(csi->cmd!=*csi->ip) { csi->ip++; skipto(csi,CS_END_CMD); /* skip code */ } csi->ip++; /* skip key */ return(0); case CS_CMDCHAR: if(csi->cmd!=*csi->ip) { csi->ip++; skipto(csi,CS_END_CMD); /* skip code */ } csi->ip++; /* skip key */ return(0); case CS_NODE_ACTION: action=*csi->ip++; return(0); case CS_NODE_STATUS: if(getnodedat(cfg.node_num,&thisnode,true)==0) { thisnode.status=*csi->ip++; putnodedat(cfg.node_num,&thisnode); } else csi->ip++; return(0); case CS_MULTINODE_CHAT: multinodechat(*csi->ip++); return(0); case CS_GETSTR: csi->logic=LOGIC_TRUE; getstr(csi->str,*csi->ip++,0); if(sys_status&SS_ABORT) { csi->str[0]=0; csi->logic=LOGIC_FALSE; } if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETLINE: getstr(csi->str,*csi->ip++,K_LINE); if(sys_status&SS_ABORT) csi->str[0]=0; if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETSTRUPR: getstr(csi->str,*csi->ip++,K_UPPER); if(sys_status&SS_ABORT) csi->str[0]=0; if(csi->str[0]=='/' && csi->str[1]) csi->cmd=csi->str[1]|0x80; else csi->cmd=csi->str[0]; return(0); case CS_GETNAME: getstr(csi->str,*csi->ip++,K_UPRLWR); if(sys_status&SS_ABORT) csi->str[0]=0; return(0); case CS_SHIFT_STR: i=*(csi->ip++); j=strlen(csi->str); if(i>j) i=j; if(i) memmove(csi->str,csi->str+i,j+1); return(0); case CS_COMPARE_KEY: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd)) || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80 && isdigit(csi->cmd&0x7f))) { csi->ip++; csi->logic=LOGIC_TRUE; } else { if(csi->cmd==*(csi->ip++)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; } return(0); case CS_COMPARE_CHAR: if(csi->cmd==*(csi->ip++)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_SET_USER_LEVEL: useron.level=*(csi->ip++); putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10)); return(0); case CS_SET_USER_STRING: csi->logic=LOGIC_FALSE; if(!csi->str[0]) { csi->ip++; return(0); } switch(*(csi->ip++)) { case USER_STRING_ALIAS: if(!isalpha(csi->str[0]) || trashcan(csi->str,"name")) break; i=matchuser(&cfg,csi->str,TRUE /*sysop_alias*/); if(i && i!=useron.number) break; sprintf(useron.alias,"%.*s",LEN_ALIAS,csi->str); putuserrec(&cfg,useron.number,U_ALIAS,LEN_ALIAS,useron.alias); putusername(&cfg,useron.number,useron.alias); csi->logic=LOGIC_TRUE; break; case USER_STRING_REALNAME: if(trashcan(csi->str,"name")) break; if(cfg.uq&UQ_DUPREAL && userdatdupe(useron.number,U_NAME,LEN_NAME,csi->str)) break; sprintf(useron.name,"%.*s",LEN_NAME,csi->str); putuserrec(&cfg,useron.number,U_NAME,LEN_NAME ,useron.name); csi->logic=LOGIC_TRUE; break; case USER_STRING_HANDLE: if(trashcan(csi->str,"name")) break; if(cfg.uq&UQ_DUPHAND && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE,csi->str)) break; sprintf(useron.handle,"%.*s",LEN_HANDLE,csi->str); putuserrec(&cfg,useron.number,U_HANDLE,LEN_HANDLE ,useron.handle); csi->logic=LOGIC_TRUE; break; case USER_STRING_COMPUTER: sprintf(useron.comp,"%.*s",LEN_COMP,csi->str); putuserrec(&cfg,useron.number,U_COMP,LEN_COMP ,useron.comp); csi->logic=LOGIC_TRUE; break; case USER_STRING_NOTE: sprintf(useron.note,"%.*s",LEN_NOTE,csi->str); putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE ,useron.note); csi->logic=LOGIC_TRUE; break; case USER_STRING_ADDRESS: sprintf(useron.address,"%.*s",LEN_ADDRESS,csi->str); putuserrec(&cfg,useron.number,U_ADDRESS,LEN_ADDRESS ,useron.address); csi->logic=LOGIC_TRUE; break; case USER_STRING_LOCATION: sprintf(useron.location,"%.*s",LEN_LOCATION,csi->str); putuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION ,useron.location); csi->logic=LOGIC_TRUE; break; case USER_STRING_ZIPCODE: sprintf(useron.zipcode,"%.*s",LEN_ZIPCODE,csi->str); putuserrec(&cfg,useron.number,U_ZIPCODE,LEN_ZIPCODE ,useron.zipcode); csi->logic=LOGIC_TRUE; break; case USER_STRING_PASSWORD: sprintf(useron.pass,"%.*s",LEN_PASS,csi->str); putuserrec(&cfg,useron.number,U_PASS,LEN_PASS ,useron.pass); csi->logic=LOGIC_TRUE; break; case USER_STRING_BIRTHDAY: if(!getage(&cfg,csi->str)) break; sprintf(useron.birth,"%.*s",LEN_BIRTH,csi->str); putuserrec(&cfg,useron.number,U_BIRTH,LEN_BIRTH ,useron.birth); csi->logic=LOGIC_TRUE; break; case USER_STRING_PHONE: if(trashcan(csi->str,"phone")) break; sprintf(useron.phone,"%.*s",LEN_PHONE,csi->str); putuserrec(&cfg,useron.number,U_PHONE,LEN_PHONE ,useron.phone); csi->logic=LOGIC_TRUE; break; case USER_STRING_MODEM: sprintf(useron.modem,"%.*s",LEN_MODEM,csi->str); putuserrec(&cfg,useron.number,U_MODEM,LEN_MODEM ,useron.phone); csi->logic=LOGIC_TRUE; break; case USER_STRING_COMMENT: sprintf(useron.comment,"%.*s",LEN_COMMENT,csi->str); putuserrec(&cfg,useron.number,U_COMMENT,LEN_COMMENT ,useron.comment); csi->logic=LOGIC_TRUE; break; case USER_STRING_NETMAIL: sprintf(useron.netmail,"%.*s",LEN_NETMAIL,csi->str); putuserrec(&cfg,useron.number,U_NETMAIL,LEN_NETMAIL ,useron.netmail); csi->logic=LOGIC_TRUE; break; default: errormsg(WHERE,ERR_CHK,"user string type",*(csi->ip-1)); return(0); } return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } } /*********************************/ /* Single Byte Instrcutions ONLY */ /*********************************/ switch(*(csi->ip++)) { case CS_ONE_MORE_BYTE: /* Just one MORE byte */ switch(*(csi->ip++)) { case CS_OFFLINE: csi->misc|=CS_OFFLINE_EXEC; return(0); case CS_ONLINE: csi->misc&=~CS_OFFLINE_EXEC; return(0); case CS_NEWUSER: if(newuser()) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_LOGON: if(logon()) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_LOGOUT: logout(); return(0); case CS_EXIT: return(1); case CS_LOOP_BEGIN: if(csi->loops<MAX_LOOPDEPTH) csi->loop_home[csi->loops++]=(csi->ip-1); return(0); case CS_BREAK_LOOP: if(csi->loops) { skipto(csi,CS_END_LOOP); csi->ip+=2; csi->loops--; } return(0); case CS_END_LOOP: case CS_CONTINUE_LOOP: if(csi->loops) csi->ip=csi->loop_home[csi->loops-1]; return(0); default: errormsg(WHERE,ERR_CHK,"one byte extended function" ,*(csi->ip-1)); return(0); } case CS_CRLF: CRLF; return(0); case CS_CLS: CLS; return(0); case CS_PAUSE: pause(); return(0); case CS_PAUSE_RESET: lncntr=0; return(0); case CS_GETLINES: ansi_getlines(); return(0); case CS_HANGUP: hangup(); return(0); case CS_LOGKEY: logch(csi->cmd,0); return(0); case CS_LOGKEY_COMMA: logch(csi->cmd,1); return(0); case CS_LOGSTR: log(csi->str); return(0); case CS_CHKSYSPASS: csi->logic=!chksyspass(); return(0); case CS_PUT_NODE: if(getnodedat(cfg.node_num,&thisnode,true)==0) putnodedat(cfg.node_num,&thisnode); return(0); case CS_SYNC: SYNC; return(0); case CS_ASYNC: ASYNC; return(0); case CS_GETTIMELEFT: gettimeleft(); return(0); case CS_RETURN: if(!csi->rets) return(1); csi->ip=csi->ret[--csi->rets]; return(0); case CS_GETKEY: csi->cmd=getkey(K_UPPER); return(0); case CS_GETCHAR: csi->cmd=getkey(0); return(0); case CS_INKEY: csi->cmd=toupper(inkey(K_NONE,1)); if(csi->cmd) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_INCHAR: csi->cmd=inkey(K_NONE,1); if(csi->cmd) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_GETKEYE: csi->cmd=getkey(K_UPPER); if(csi->cmd=='/') { outchar('/'); csi->cmd=getkey(K_UPPER); csi->cmd|=0x80; } return(0); case CS_GETFILESPEC: if(getfilespec(csi->str)) csi->logic=LOGIC_TRUE; else csi->logic=LOGIC_FALSE; return(0); case CS_SAVELINE: SAVELINE; return(0); case CS_RESTORELINE: RESTORELINE; return(0); case CS_SELECT_SHELL: csi->logic=select_shell() ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_SET_SHELL: csi->logic=LOGIC_TRUE; for(i=0;i<cfg.total_shells;i++) if(!stricmp(csi->str,cfg.shell[i]->code) && chk_ar(cfg.shell[i]->ar,&useron,&client)) break; if(i<cfg.total_shells) { useron.shell=i; putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code); } else csi->logic=LOGIC_FALSE; return(0); case CS_SELECT_EDITOR: csi->logic=select_editor() ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_SET_EDITOR: csi->logic=LOGIC_TRUE; for(i=0;i<cfg.total_xedits;i++) if(!stricmp(csi->str,cfg.xedit[i]->code) && chk_ar(cfg.xedit[i]->ar,&useron,&client)) break; if(i<cfg.total_xedits) { useron.xedit=i+1; putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code); } else csi->logic=LOGIC_FALSE; return(0); case CS_CLEAR_ABORT: sys_status&=~SS_ABORT; return(0); case CS_FINDUSER: i=finduser(csi->str); if(i) { csi->logic=LOGIC_TRUE; username(&cfg,i,csi->str); } else csi->logic=LOGIC_FALSE; return(0); case CS_UNGETKEY: ungetkey(csi->cmd&0x7f); return(0); case CS_UNGETSTR: j=strlen(csi->str); for(i=0;i<j;i++) ungetkey(csi->str[i]); return(0); case CS_PRINTKEY: if((csi->cmd&0x7f)>=' ') outchar(csi->cmd&0x7f); return(0); case CS_PRINTSTR: putmsg(csi->str,P_SAVEATR|P_NOABORT|P_NOATCODES); return(0); case CS_CMD_HOME: if(csi->cmdrets<MAX_CMDRETS) csi->cmdret[csi->cmdrets++]=(csi->ip-1); return(0); case CS_END_CMD: if(csi->cmdrets) csi->ip=csi->cmdret[--csi->cmdrets]; return(0); case CS_CMD_POP: if(csi->cmdrets) csi->cmdrets--; return(0); case CS_IF_TRUE: if(csi->logic!=LOGIC_TRUE) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_GREATER: if(csi->logic!=LOGIC_GREATER) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_GREATER_OR_EQUAL: if(csi->logic!=LOGIC_GREATER && csi->logic!=LOGIC_EQUAL) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_LESS: if(csi->logic!=LOGIC_LESS) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_LESS_OR_EQUAL: if(csi->logic!=LOGIC_LESS && csi->logic!=LOGIC_EQUAL) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_IF_FALSE: if(csi->logic==LOGIC_TRUE) { skipto(csi,CS_ELSEORENDIF); csi->ip++; } return(0); case CS_ELSE: skipto(csi,CS_ENDIF); csi->ip++; return(0); case CS_END_CASE: skipto(csi,CS_END_SWITCH); csi->misc&=~CS_IN_SWITCH; csi->ip++; return(0); case CS_DEFAULT: case CS_END_SWITCH: csi->misc&=~CS_IN_SWITCH; return(0); case CS_ENDIF: return(0); default: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1)); return(0); } }
int iso_utf8_2gsm(char* source, int size, char* destination, int max) { int source_count=0; int dest_count=0; int found=0; char newch; char logtmp[51]; char tmpch; destination[dest_count]=0; if (source==0 || size <= 0) return 0; #ifdef DEBUGMSG log_charconv = 1; #endif if (log_charconv) { *logch_buffer = 0; logch("!! iso_utf8_2gsm(source=%.*s, size=%i)", size, source, size); logch(NULL); } // Convert each character until end of string while (source_count<size && dest_count<max) { found = char2gsm(source[source_count], &newch); if (found == 2) { if (dest_count >= max -2) break; destination[dest_count++] = 0x1B; } if (found >= 1) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%02X[%c]", (unsigned char)source[source_count], prch(source[source_count])); if (found > 1 || source[source_count] != newch) { sprintf(strchr(logtmp, 0), "->%s%02X", (found == 2)? "Esc-" : "", (unsigned char)newch); if (gsm2char(newch, &tmpch, found)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); } logch("%s ", logtmp); } } if (found == 0 && outgoing_utf8) { // ASCII and UTF-8 table: http://members.dslextreme.com/users/kkj/webtools/ascii_utf8_table.html // Good converter: http://www.macchiato.com/unicode/convert.html unsigned int c; int iterations = 0; // 3.1beta7: If UTF-8 decoded character is not found from tables, decoding is ignored: int saved_source_count = source_count; char sourcechars[51]; c = source[source_count]; if (log_charconv) sprintf(sourcechars, "%02X", (unsigned char)source[source_count]); // 3.1beta7: Check if there is enough characters left. // Following bytes in UTF-8 should begin with 10xx xxxx // which means 0x80 ... 0xBF if (((c & 0xFF) >= 0xC2 && (c & 0xFF) <= 0xC7) || ((c & 0xFF) >= 0xD0 && (c & 0xFF) <= 0xD7)) { if (source_count < size -1 && (source[source_count +1] & 0xC0) == 0x80) { // 110xxxxx c &= 0x1F; iterations = 1; } } else if ((c & 0xFF) >= 0xE0 && (c & 0xFF) <= 0xE7) { if (source_count < size -2 && (source[source_count +1] & 0xC0) == 0x80 && (source[source_count +2] & 0xC0) == 0x80) { // 1110xxxx c &= 0x0F; iterations = 2; } } else if ((c & 0xFF) >= 0xF0 && (c & 0xFF) <= 0xF4) { if (source_count < size -3 && (source[source_count +1] & 0xC0) == 0x80 && (source[source_count +2] & 0xC0) == 0x80 && (source[source_count +3] & 0xC0) == 0x80) { // 11110xxx c &= 0x07; iterations = 3; } } if (iterations > 0) { int i; for (i = 0; i < iterations; i++) { c = (c << 6) | (source[++source_count] -0x80); if (log_charconv) sprintf(strchr(sourcechars, 0), "%02X", (unsigned char)source[source_count]); } // Euro character is 20AC in UTF-8, but A4 in ISO-8859-15: if ((c & 0xFF) == 0xAC) c = 0xA4; found = char2gsm((char)c, &newch); if (found == 2) { if (dest_count >= max -2) break; destination[dest_count++] = 0x1B; } if (found >= 1) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%s(%02X[%c])->%s%02X", sourcechars, (unsigned char)c, prch(c), (found == 2)? "Esc-" : "", (unsigned char)newch); if (gsm2char(newch, &tmpch, found)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } else { found = special_char2gsm((char)c, &newch); if (found) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%s(%02X[%c])~>%02X", sourcechars, (unsigned char)c, prch(c), (unsigned char)newch); if (gsm2char(newch, &tmpch, 1)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } else source_count = saved_source_count; } } } // 3.1beta7: Try additional table: if (found == 0) { found = special_char2gsm(source[source_count], &newch); if (found) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%02X[%c]~>%02X", (unsigned char)source[source_count], prch(source[source_count]), (unsigned char)newch); if (gsm2char(newch, &tmpch, 1)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } } if (found==0) { writelogfile0(LOG_NOTICE, 0, tb_sprintf("Cannot convert %i. character %c 0x%2X to GSM, you might need to update the translation tables.", source_count +1, source[source_count], source[source_count])); #ifdef DEBUGMSG printf("%s\n", tb); #endif } source_count++; } if (log_charconv) logch(NULL); // Terminate destination string with 0, however 0x00 are also allowed within the string. destination[dest_count]=0; return dest_count; }
int sbbs_t::exec_file(csi_t *csi) { char str[256],ch; int s; uint i,j,x,y; file_t f; switch(*(csi->ip++)) { case CS_FILE_SELECT_AREA: csi->logic=LOGIC_FALSE; if(!usrlibs) return(0); while(online) { j=0; if(usrlibs>1) { sprintf(str,"%smenu/libs.*", cfg.text_dir); if(fexist(str)) menu("libs"); else { bputs(text[CfgLibLstHdr]); for(i=0;i<usrlibs && !msgabort();i++) { if(i==curlib) outchar('*'); else outchar(' '); if(i<9) outchar(' '); if(i<99) outchar(' '); bprintf(text[CfgLibLstFmt] ,i+1,cfg.lib[usrlib[i]]->lname); } } sprintf(str,text[JoinWhichLib],curlib+1); mnemonics(str); j=getnum(usrlibs); if((int)j==-1) return(0); if(!j) j=curlib; else j--; } sprintf(str,"%smenu/dirs%u.*", cfg.text_dir, usrlib[j]+1); if(fexist(str)) { sprintf(str,"dirs%u",usrlib[j]+1); menu(str); } else { CLS; bprintf(text[DirLstHdr], cfg.lib[usrlib[j]]->lname); for(i=0;i<usrdirs[j] && !msgabort();i++) { if(i==curdir[j]) outchar('*'); else outchar(' '); sprintf(str,text[DirLstFmt],i+1 ,cfg.dir[usrdir[j][i]]->lname,nulstr ,getfiles(&cfg,usrdir[j][i])); if(i<9) outchar(' '); if(i<99) outchar(' '); bputs(str); } } sprintf(str,text[JoinWhichDir],curdir[j]+1); mnemonics(str); i=getnum(usrdirs[j]); if((int)i==-1) { if(usrlibs==1) return(0); continue; } if(!i) i=curdir[j]; else i--; curlib=j; curdir[curlib]=i; csi->logic=LOGIC_TRUE; return(0); } return(0); case CS_FILE_GET_DIR_NUM: if(useron.misc&COLDKEYS) { i=atoi(csi->str); if(i && i<=usrdirs[curlib] && usrlibs) curdir[curlib]=i-1; return(0); } ch=getkey(K_UPPER); outchar(ch); if((ch&0xf)*10U<=usrdirs[curlib] && (ch&0xf) && usrlibs) { i=(ch&0xf)*10; ch=getkey(K_UPPER); if(!isdigit(ch) && ch!=CR) { ungetkey(ch); curdir[curlib]=(i/10)-1; return(0); } outchar(ch); if(ch==CR) { curdir[curlib]=(i/10)-1; return(0); } logch(ch,0); i+=ch&0xf; if(i*10<=usrdirs[curlib]) { /* 100+ dirs */ i*=10; ch=getkey(K_UPPER); if(!isdigit(ch) && ch!=CR) { ungetkey(ch); curdir[curlib]=(i/10)-1; return(0); } outchar(ch); if(ch==CR) { curdir[curlib]=(i/10)-1; return(0); } logch(ch,0); i+=ch&0xf; } if(i<=usrdirs[curlib]) curdir[curlib]=i-1; return(0); } if((ch&0xf)<=(int)usrdirs[curlib] && (ch&0xf) && usrlibs) curdir[curlib]=(ch&0xf)-1; return(0); case CS_FILE_GET_LIB_NUM: if(useron.misc&COLDKEYS) { i=atoi(csi->str); if(i && i<=usrlibs) curlib=i-1; return(0); } ch=getkey(K_UPPER); outchar(ch); if((ch&0xf)*10U<=usrlibs && (ch&0xf)) { i=(ch&0xf)*10; ch=getkey(K_UPPER); if(!isdigit(ch) && ch!=CR) { ungetkey(ch); curlib=(i/10)-1; return(0); } outchar(ch); if(ch==CR) { curlib=(i/10)-1; return(0); } logch(ch,0); i+=ch&0xf; if(i<=usrlibs) curlib=i-1; return(0); } if((ch&0xf)<=(int)usrlibs && (ch&0xf)) curlib=(ch&0xf)-1; return(0); case CS_FILE_SHOW_LIBRARIES: if(!usrlibs) return(0); sprintf(str,"%smenu/libs.*", cfg.text_dir); if(fexist(str)) { menu("libs"); return(0); } bputs(text[LibLstHdr]); for(i=0;i<usrlibs && !msgabort();i++) { if(i==curlib) outchar('*'); else outchar(' '); if(i<9) outchar(' '); bprintf(text[LibLstFmt],i+1 ,cfg.lib[usrlib[i]]->lname,nulstr,usrdirs[i]); } return(0); case CS_FILE_SHOW_DIRECTORIES: if(!usrlibs) return(0); sprintf(str,"%smenu/dirs%u.*", cfg.text_dir, usrlib[curlib]+1); if(fexist(str)) { sprintf(str,"dirs%u",usrlib[curlib]+1); menu(str); return(0); } CRLF; bprintf(text[DirLstHdr],cfg.lib[usrlib[curlib]]->lname); for(i=0;i<usrdirs[curlib] && !msgabort();i++) { if(i==curdir[curlib]) outchar('*'); else outchar(' '); sprintf(str,text[DirLstFmt],i+1 ,cfg.dir[usrdir[curlib][i]]->lname,nulstr ,getfiles(&cfg,usrdir[curlib][i])); if(i<9) outchar(' '); if(i<99) outchar(' '); bputs(str); } return(0); case CS_FILE_LIBRARY_UP: curlib++; if(curlib>=usrlibs) curlib=0; return(0); case CS_FILE_LIBRARY_DOWN: if(!curlib) curlib=usrlibs-1; else curlib--; return(0); case CS_FILE_DIRECTORY_UP: if(!usrlibs) return(0); curdir[curlib]++; if(curdir[curlib]>=usrdirs[curlib]) curdir[curlib]=0; return(0); case CS_FILE_DIRECTORY_DOWN: if(!usrlibs) return(0); if(!curdir[curlib]) curdir[curlib]=usrdirs[curlib]-1; else curdir[curlib]--; return(0); case CS_FILE_SET_AREA: csi->logic=LOGIC_TRUE; for(i=0;i<usrlibs;i++) for(j=0;j<usrdirs[i];j++) if(!stricmp(csi->str,cfg.dir[usrdir[i][j]]->code)) { curlib=i; curdir[i]=j; return(0); } csi->logic=LOGIC_FALSE; return(0); case CS_FILE_SET_LIBRARY: csi->logic=LOGIC_TRUE; for(i=0;i<usrlibs;i++) if(!stricmp(cfg.lib[usrlib[i]]->sname,csi->str)) break; if(i<usrlibs) curlib=i; else csi->logic=LOGIC_FALSE; return(0); case CS_FILE_UPLOAD: csi->logic=LOGIC_FALSE; if(usrlibs) { i=usrdir[curlib][curdir[curlib]]; if(cfg.upload_dir!=INVALID_DIR && !dir_op(i) && !(useron.exempt&FLAG('U')) && !chk_ar(cfg.dir[i]->ul_ar,&useron,&client)) i=cfg.upload_dir; } else i=cfg.upload_dir; csi->logic=upload(i) ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_FILE_UPLOAD_USER: csi->logic=LOGIC_FALSE; if(cfg.user_dir==INVALID_DIR) { bputs(text[NoUserDir]); return(0); } csi->logic=upload(cfg.user_dir) ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_FILE_UPLOAD_SYSOP: csi->logic=LOGIC_FALSE; if(cfg.sysop_dir==INVALID_DIR) { bputs(text[NoSysopDir]); return(0); } csi->logic=upload(cfg.sysop_dir) ? LOGIC_TRUE:LOGIC_FALSE; return(0); case CS_FILE_DOWNLOAD: if(!usrlibs) return(0); if(useron.rest&FLAG('D')) { bputs(text[R_Download]); return(0); } padfname(csi->str,str); strupr(str); if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_DOWNLOAD)) { bputs(text[SearchingAllDirs]); for(i=0;i<usrdirs[curlib];i++) if(i!=curdir[curlib] && (s=listfileinfo(usrdir[curlib][i],str,FI_DOWNLOAD))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); bputs(text[SearchingAllLibs]); for(i=0;i<usrlibs;i++) { if(i==curlib) continue; for(j=0;j<usrdirs[i];j++) if((s=listfileinfo(usrdir[i][j],str,FI_DOWNLOAD))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); } } return(0); case CS_FILE_DOWNLOAD_USER: /* Download from user dir */ csi->logic=LOGIC_FALSE; if(cfg.user_dir==INVALID_DIR) { bputs(text[NoUserDir]); return(0); } if(useron.rest&FLAG('D')) { bputs(text[R_Download]); return(0); } CRLF; if(!listfileinfo(cfg.user_dir,nulstr,FI_USERXFER)) bputs(text[NoFilesForYou]); else csi->logic=LOGIC_TRUE; return(0); case CS_FILE_DOWNLOAD_BATCH: if(batdn_total && (text[DownloadBatchQ][0]==0 || yesno(text[DownloadBatchQ]))) { start_batch_download(); csi->logic=LOGIC_TRUE; } else csi->logic=LOGIC_FALSE; return(0); case CS_FILE_BATCH_ADD_LIST: batch_add_list(csi->str); return(0); case CS_FILE_BATCH_ADD: csi->logic=LOGIC_FALSE; if(!csi->str[0]) return(0); padfname(csi->str,f.name); for(x=y=0;x<usrlibs;x++) { for(y=0;y<usrdirs[x];y++) if(findfile(&cfg,usrdir[x][y],f.name)) break; if(y<usrdirs[x]) break; } if(x>=usrlibs) return(0); f.dir=usrdir[x][y]; getfileixb(&cfg,&f); f.size=0; getfiledat(&cfg,&f); addtobatdl(&f); csi->logic=LOGIC_TRUE; return(0); case CS_FILE_BATCH_CLEAR: if(!batdn_total) { csi->logic=LOGIC_FALSE; return(0); } csi->logic=LOGIC_TRUE; for(i=0;i<batdn_total;i++) { f.dir=batdn_dir[i]; f.datoffset=batdn_offset[i]; f.size=batdn_size[i]; strcpy(f.name,batdn_name[i]); closefile(&f); } batdn_total=0; return(0); case CS_FILE_VIEW: if(!usrlibs) return(0); padfname(csi->str,str); strupr(str); csi->logic=LOGIC_TRUE; if(listfiles(usrdir[curlib][curdir[curlib]],str,0,FL_VIEW)) return(0); bputs(text[SearchingAllDirs]); for(i=0;i<usrdirs[curlib];i++) { if(i==curdir[curlib]) continue; if(listfiles(usrdir[curlib][i],str,0,FL_VIEW)) break; } if(i<usrdirs[curlib]) return(0); bputs(text[SearchingAllLibs]); for(i=0;i<usrlibs;i++) { if(i==curlib) continue; for(j=0;j<usrdirs[i];j++) if(listfiles(usrdir[i][j],str,0,FL_VIEW)) return(0); } csi->logic=LOGIC_FALSE; bputs(text[FileNotFound]); return(0); case CS_FILE_LIST: /* List files in current dir */ if(!usrlibs) return(0); csi->logic=LOGIC_FALSE; if(!getfiles(&cfg,usrdir[curlib][curdir[curlib]])) { bputs(text[EmptyDir]); return(0); } padfname(csi->str,str); strupr(str); s=listfiles(usrdir[curlib][curdir[curlib]],str,0,0); if(s>1) { bprintf(text[NFilesListed],s); } csi->logic=!s; return(0); case CS_FILE_LIST_EXTENDED: /* Extended Information on files */ if(!usrlibs) return(0); padfname(csi->str,str); strupr(str); if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_INFO)) { bputs(text[SearchingAllDirs]); for(i=0;i<usrdirs[curlib];i++) if(i!=curdir[curlib] && (s=listfileinfo(usrdir[curlib][i] ,str,FI_INFO))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); bputs(text[SearchingAllLibs]); for(i=0;i<usrlibs;i++) { if(i==curlib) continue; for(j=0;j<usrdirs[i];j++) if((s=listfileinfo(usrdir[i][j],str,FI_INFO))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); } } return(0); case CS_FILE_FIND_TEXT: /* Find text in descriptions */ scandirs(FL_FINDDESC); return(0); case CS_FILE_FIND_TEXT_ALL: /* Find text in descriptions */ scanalldirs(FL_FINDDESC); return(0); case CS_FILE_FIND_NAME: /* Find text in descriptions */ scandirs(FL_NO_HDR); return(0); case CS_FILE_FIND_NAME_ALL: /* Find text in descriptions */ scanalldirs(FL_NO_HDR); return(0); case CS_FILE_BATCH_SECTION: batchmenu(); return(0); case CS_FILE_TEMP_SECTION: temp_xfer(); return(0); case CS_FILE_PTRS_CFG: csi->logic=!inputnstime(&ns_time); return(0); case CS_FILE_NEW_SCAN: scandirs(FL_ULTIME); return(0); case CS_FILE_NEW_SCAN_ALL: scanalldirs(FL_ULTIME); return(0); case CS_FILE_REMOVE: if(!usrlibs) return(0); if(useron.rest&FLAG('R')) { bputs(text[R_RemoveFiles]); return(0); } padfname(csi->str,str); strupr(str); if(!listfileinfo(usrdir[curlib][curdir[curlib]],str,FI_REMOVE)) { if(cfg.user_dir!=INVALID_DIR && cfg.user_dir!=usrdir[curlib][curdir[curlib]]) if((s=listfileinfo(cfg.user_dir,str,FI_REMOVE))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); bputs(text[SearchingAllDirs]); for(i=0;i<usrdirs[curlib];i++) if(i!=curdir[curlib] && i!=cfg.user_dir && (s=listfileinfo(usrdir[curlib][i],str,FI_REMOVE))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); bputs(text[SearchingAllLibs]); for(i=0;i<usrlibs;i++) { if(i==curlib || i==cfg.user_dir) continue; for(j=0;j<usrdirs[i]; j++) if((s=listfileinfo(usrdir[i][j],str,FI_REMOVE))!=0) if(s==-1 || (!strchr(str,'?') && !strchr(str,'*'))) return(0); } } return(0); } errormsg(WHERE,ERR_CHK,"shell function",*(csi->ip-1)); return(0); }