saacproto_util.c
上传用户:qys8201
上传日期:2021-12-11
资源大小:978k
文件大小:42k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #define _SAACPROTOUTIL_C_
  2. #include "version.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #ifndef WIN32
  7. #include <unistd.h>
  8. #include <strings.h>
  9. #endif
  10. #include "main.h"
  11. #include "saacproto_util.h"
  12. #ifdef saacproto__ENCRYPT
  13. long saacproto_ringoCompressor( unsigned char *code , long codelen , unsigned char *text , long textlen);
  14. long saacproto_ringoDecompressor( unsigned char *text , long textlen , unsigned char *code , long codelen);
  15. #endif
  16. /*
  17.   lsrpc routines
  18. */
  19. int saacproto_AllocateCommonWork(int bufsiz)
  20. {
  21. saacproto.workbufsize = bufsiz;
  22. saacproto.work = NULL;
  23. saacproto.arraywork = NULL;
  24. saacproto.escapework = NULL;
  25. saacproto.val_str = NULL;
  26. saacproto.token_list = NULL;
  27. saacproto.cryptwork = NULL;
  28. saacproto.jencodecopy = NULL;
  29. saacproto.jencodeout = NULL;
  30. saacproto.compresswork = NULL;
  31. saacproto.work = (char*)calloc( 1, saacproto.workbufsize );
  32. saacproto.arraywork = (char*)calloc( 1, saacproto.workbufsize );
  33. saacproto.escapework = (char*)calloc( 1, saacproto.workbufsize );
  34. saacproto.val_str = (char*)calloc( 1, saacproto.workbufsize );
  35. saacproto.token_list = (char**)calloc( 1, saacproto.workbufsize *sizeof( char** ) );
  36. saacproto.cryptwork = (char*)calloc( 1, saacproto.workbufsize * 3 );
  37. saacproto.jencodecopy = (char*)calloc( 1, saacproto.workbufsize * 3 );
  38. saacproto.jencodeout = (char*)calloc( 1, saacproto.workbufsize * 3 );
  39. saacproto.compresswork = (char*)calloc( 1, saacproto.workbufsize * 3 );
  40. memset( saacproto.work , 0, saacproto.workbufsize );
  41. memset( saacproto.arraywork , 0, saacproto.workbufsize );
  42. memset( saacproto.escapework , 0, saacproto.workbufsize );
  43. memset( saacproto.val_str , 0, saacproto.workbufsize );
  44. memset( (char*)saacproto.token_list ,0,  saacproto.workbufsize*sizeof(char**) );
  45. memset( saacproto.cryptwork , 0, saacproto.workbufsize*3 );
  46. memset( saacproto.jencodecopy , 0, saacproto.workbufsize*3 );
  47. memset( saacproto.jencodeout , 0, saacproto.workbufsize*3 );
  48. memset( saacproto.compresswork , 0, saacproto.workbufsize*3 );
  49. if( saacproto.work == NULL ||
  50.    saacproto.arraywork == NULL ||
  51.    saacproto.escapework == NULL ||
  52.    saacproto.val_str == NULL ||
  53.    saacproto.token_list == NULL ||
  54.    saacproto.cryptwork == NULL ||
  55.    saacproto.jencodecopy == NULL ||
  56.    saacproto.jencodeout == NULL ||
  57.    saacproto.compresswork == NULL ){
  58.     free( saacproto.work);free( saacproto.val_str);
  59.     free( saacproto.escapework);free( saacproto.arraywork );
  60.     free( saacproto.token_list);free( saacproto.cryptwork );
  61.     free( saacproto.jencodecopy);free( saacproto.jencodeout );
  62.     free( saacproto.compresswork );
  63.     return -1;
  64. }
  65. return 0;
  66. }
  67. /**********
  68.   Get message information from a network input
  69. **********/
  70. void saacproto_GetMessageInfo( int *id , char *funcname , int len, char **tk )
  71. {
  72. if( tk[0] == NULL || tk[1] == NULL ){
  73. *id = 0;
  74. saacproto_strcpysafe( funcname , "" , len );
  75. return;
  76. }
  77. *id =  strtoul( tk[0] ,NULL,10);
  78. saacproto_strcpysafe( funcname , tk[1] , len );
  79. return;
  80. }
  81. /********************************************
  82.   string utilities
  83. *********************************************/
  84. void saacproto_strcpysafe( char *dest, char *src, int maxlen )
  85. {
  86. int i;
  87. for(i=0;i<maxlen-1;i++){
  88. dest[i] = src[i];
  89. if( src[i]==0)break;
  90. }
  91. dest[i]=0;
  92. }
  93. void saacproto_strcatsafe( char *dest , char *src , int maxlen )
  94. {
  95. int i,j;
  96. for(i=0;i<maxlen-1;i++){
  97. if( dest[i] == 0 ){
  98. for(j=i;j<maxlen-1;j++){
  99. dest[j]= src[j-i];
  100. if( src[j-i] == 0 )break;
  101. }
  102. dest[j]=0;
  103. break;
  104. }
  105. }
  106. }
  107. char*saacproto_mkstr_int( int i )
  108. {
  109. #define MKSTR_INT(v) saacproto_Ltoa( (long)(v)) 
  110. saacproto_strcpysafe( saacproto.val_str ,  (char*)MKSTR_INT(i) , saacproto.workbufsize );
  111. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  112. return saacproto.val_str;
  113. }
  114. char*saacproto_mkstr_u_int( unsigned int i )
  115. {
  116. #define MKSTR_U_INT(v) saacproto_Ultoa( (unsigned long ) (v) )
  117. saacproto_strcpysafe( saacproto.val_str , MKSTR_U_INT(i) , saacproto.workbufsize );
  118. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  119. return saacproto.val_str;
  120. }
  121. char*saacproto_mkstr_long( long l )
  122. {
  123. #define MKSTR_LONG(v) saacproto_Ltoa( v ) 
  124. saacproto_strcpysafe( saacproto.val_str , MKSTR_LONG(l) , saacproto.workbufsize );
  125. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  126. return saacproto.val_str;
  127. }
  128. char*saacproto_mkstr_u_long( unsigned long l )
  129. {
  130. #define MKSTR_U_LONG(v) saacproto_Ultoa(v ) 
  131. saacproto_strcpysafe( saacproto.val_str , MKSTR_U_LONG(l) , saacproto.workbufsize );
  132. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  133. return saacproto.val_str;
  134. }
  135. char*saacproto_mkstr_short( short s )
  136. {
  137. #define MKSTR_SHORT16(v)    saacproto_Ltoa( (long)((int)(v) ))
  138. saacproto_strcpysafe( saacproto.val_str , MKSTR_SHORT16(s) , saacproto.workbufsize );
  139. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  140. return saacproto.val_str;
  141. }
  142. char*saacproto_mkstr_u_short( short s )
  143. {
  144. #define MKSTR_U_SHORT16(v)   saacproto_Ltoa( (long)(  ((long)(v)) & 0xffff ))
  145. saacproto_strcpysafe( saacproto.val_str , MKSTR_U_SHORT16(s) , saacproto.workbufsize );
  146. saacproto_strcatsafe( saacproto.val_str ," " , saacproto.workbufsize );
  147. return saacproto.val_str;
  148. }
  149. char*saacproto_mkstr_char( char c )
  150. {
  151. #define MKSTR_CHAR8(v)   saacproto_Ltoa( ( long)((int)(v)))
  152. saacproto_strcpysafe( saacproto.val_str , MKSTR_CHAR8(c) , saacproto.workbufsize );
  153. saacproto_strcatsafe( saacproto.val_str ," ", saacproto.workbufsize );
  154. return saacproto.val_str;
  155. }
  156. char*saacproto_mkstr_u_char( char c)
  157. {
  158. #define MKSTR_U_CHAR8(v)   saacproto_Ltoa( (long)( ((long)(v)) & 0xff ))
  159. saacproto_strcpysafe( saacproto.val_str , MKSTR_U_CHAR8(c) , saacproto.workbufsize );
  160. saacproto_strcatsafe( saacproto.val_str ," "  , saacproto.workbufsize );
  161. return saacproto.val_str;
  162. }
  163. char*saacproto_mkstr_string( char*a )
  164. {
  165. char *ret = saacproto_escapeString( a );
  166. saacproto_strcatsafe( ret , " ", saacproto.workbufsize );
  167. return ret;
  168. }
  169. char*saacproto_mkstr_float(float f )
  170. {
  171. sprintf( saacproto.val_str , "%f " , f );
  172. return saacproto.val_str;
  173. }
  174. char*saacproto_mkstr_double( double d )
  175. {
  176. sprintf( saacproto.val_str , "%f " , d );
  177. return saacproto.val_str;
  178. }
  179. char*saacproto_mkstr_int_array( int size , int *array )
  180. {
  181. #define MKSTR_ARRAYMACRO( func) 
  182. {
  183.  int i;
  184.          saacproto.arraywork[0] = '';
  185.  for(i=0;i<size;i++){   
  186.              saacproto_strcatsafe( saacproto.arraywork , func(array[i]) , saacproto.workbufsize );
  187.  }
  188.          return saacproto.arraywork;
  189.     }
  190. MKSTR_ARRAYMACRO( saacproto_mkstr_int );
  191. }
  192. char*saacproto_mkstr_u_int_array( int size , int *array )
  193. {
  194. MKSTR_ARRAYMACRO( saacproto_mkstr_u_int );
  195. }
  196. char*saacproto_mkstr_short_array( int size , short *array )
  197. {
  198. MKSTR_ARRAYMACRO( saacproto_mkstr_short );
  199. }
  200. char*saacproto_mkstr_u_short_array( int size , short *array )
  201. {
  202. MKSTR_ARRAYMACRO( saacproto_mkstr_u_short );
  203. }
  204. char *saacproto_mkstr_char_array( int size , char *array )
  205. {
  206. MKSTR_ARRAYMACRO( saacproto_mkstr_char );
  207. }
  208. char *saacproto_mkstr_u_char_array( int size , unsigned char *array )
  209. {
  210. MKSTR_ARRAYMACRO( saacproto_mkstr_u_char );
  211. }
  212. char *saacproto_mkstr_float_array( int size , float *array )
  213. {
  214. MKSTR_ARRAYMACRO( saacproto_mkstr_float );
  215. }
  216. char *saacproto_mkstr_double_array( int size , double *array )
  217. {
  218. MKSTR_ARRAYMACRO( saacproto_mkstr_double );
  219. }
  220. /*********************
  221.    translate string into base types
  222. *********************/
  223. int saacproto_demkstr_int( char*a )
  224. {
  225. if( a == (char*)NULL)return 0;
  226. /* return (int)strtol( a ,NULL , 10);*/
  227. return saacproto_a62toi( a );
  228. }
  229. unsigned int saacproto_demkstr_u_int( char*a )
  230. {
  231. if( a == (char*)NULL)return 0;
  232. return (unsigned int ) strtoul( a ,NULL,10);
  233. }
  234. long saacproto_demkstr_long( char*a )
  235. {
  236. if( a == (char*)NULL)return 0;
  237. return (long)strtol( a , NULL , 10 );
  238. }
  239. unsigned long saacproto_demkstr_u_long(char*a )
  240. {
  241. if( a == (char*)NULL)return 0;
  242. return (unsigned long ) strtoul( a , NULL , 10 ) ;
  243. }
  244. short saacproto_demkstr_short( char*a )
  245. {
  246. if( a == (char*)NULL)return 0;
  247. return (short) strtol( a , NULL , 10 );
  248. }
  249. unsigned short saacproto_demkstr_u_short( char*a )
  250. {
  251. if( a == (char*)NULL)return 0;
  252. return (unsigned short) strtoul( a , NULL , 10 );
  253. }
  254. char saacproto_demkstr_char( char*a )
  255. {
  256. if( a == (char*)NULL)return 0;
  257. return (char) strtol(  a  , NULL , 10 );
  258. }
  259. unsigned char saacproto_demkstr_u_char( char*a )
  260. {
  261. if( a == (char*)NULL)return 0;
  262. return (unsigned char ) strtoul( a,NULL , 10 );
  263. }
  264. float saacproto_demkstr_float( char*a )
  265. {
  266. if( a == (char*)NULL)return 0.0F;
  267. return (float) atof( a);
  268. }
  269. double saacproto_demkstr_double(char*a )
  270. {
  271. if( a == (char*)NULL)return 0.0F;
  272. return (double) strtod( a , NULL );
  273. }
  274. char* saacproto_demkstr_string( char*a)
  275. {
  276. if( a == (char*)NULL){
  277. saacproto_strcpysafe( saacproto.escapework , "" , saacproto.workbufsize );
  278. return saacproto.escapework;
  279. }
  280. return saacproto_descapeString( a );
  281. }
  282. int *saacproto_demkstr_int_array( char**tk ,int *buf  ,int start , int size )
  283. {
  284. #define DEMKSTR_ARRAYMACRO( func, defaultvalue )          
  285.     {
  286.         int i;
  287.         for(i=start;i<(start+size);i++){
  288.             if( tk[i] == NULL ){   
  289.         buf[i-start]=defaultvalue ;
  290.             } else {
  291.             buf[i-start] = func( tk[i] );
  292.             }
  293.     }
  294.         return buf;
  295.     }
  296.     DEMKSTR_ARRAYMACRO( saacproto_demkstr_int , 0 );
  297. }
  298. int *saacproto_demkstr_u_int_array( char **tk , int *buf , int start , int size )
  299. {
  300. DEMKSTR_ARRAYMACRO( saacproto_demkstr_u_int , 0 );
  301. }
  302. unsigned int *saacproto_demkstr_long_array(
  303.  char **tk , unsigned int *buf , int start , int size )
  304. {
  305. DEMKSTR_ARRAYMACRO( saacproto_demkstr_long  , 0);
  306. }
  307. unsigned long *saacproto_demkstr_u_long_array(
  308.  char **tk , unsigned long *buf , int start , int size )
  309. {
  310. DEMKSTR_ARRAYMACRO( saacproto_demkstr_u_long , 0);
  311. }
  312. short *saacproto_demkstr_short_array( char **tk , short *buf , int start , int size )
  313. {
  314. DEMKSTR_ARRAYMACRO( saacproto_demkstr_short , 0);
  315. }
  316. unsigned short* saacproto_demkstr_u_short_array( 
  317.  char **tk , unsigned short *buf , int start , int size )
  318. {
  319. DEMKSTR_ARRAYMACRO( saacproto_demkstr_u_short , 0);
  320. }
  321. char *saacproto_demkstr_char_array( char **tk , char *buf , int start , int size )
  322. {
  323. DEMKSTR_ARRAYMACRO( saacproto_demkstr_u_char , 0);
  324. }
  325. unsigned char *saacproto_demkstr_u_char_array( 
  326. char **tk , unsigned char*buf , int start , int size )
  327. {
  328. DEMKSTR_ARRAYMACRO( saacproto_demkstr_u_char , 0);
  329. }
  330. float *saacproto_demkstr_float_array( char **tk , float *buf , int start , int size )
  331. {
  332. DEMKSTR_ARRAYMACRO( saacproto_demkstr_float , (float)0.0);
  333. }
  334. double *saacproto_demkstr_u_double_array( char **tk , double *buf , int start , int size )
  335. {
  336. DEMKSTR_ARRAYMACRO( saacproto_demkstr_double , (double)0.0);
  337. }
  338. char*  saacproto_escapeString( char*a )
  339. {
  340. int i,c=0;
  341. saacproto.escapework[0] = '';
  342. for(i=0;;i++){
  343. if( a[i] == '' ){
  344. saacproto.escapework[c++] = '';
  345. break;
  346. } else if( ( char )0x80 <= a[i] && a[i] <= ( char )0xFF ){
  347. // for 2 Byte Word
  348. saacproto.escapework[c++] = a[i++];
  349. saacproto.escapework[c++] = a[i];
  350. } else if( a[i] == '\' ){
  351. saacproto.escapework[c++] = '\';
  352. saacproto.escapework[c++] = '\';
  353. } else if( a[i] == ' ' ){
  354. saacproto.escapework[c++] = '\';
  355. saacproto.escapework[c++] = 'S';
  356. } else if( a[i] == 'n' ){
  357. saacproto.escapework[c++] = '\';
  358. saacproto.escapework[c++] = 'n';
  359. } else if( a[i] == 'r' ){
  360. saacproto.escapework[c++] = '\';
  361. saacproto.escapework[c++] = 'r';
  362. } else {
  363. saacproto.escapework[c++] = a[i];
  364. }
  365. }
  366. return saacproto.escapework;
  367. }
  368. char* saacproto_descapeString( char*a )
  369. {
  370. int i ,c =0;
  371. saacproto.escapework[0] = '';
  372. for(i=0;;i++){
  373. if( a[i] == '' ){
  374. saacproto.escapework[c++]='';
  375. break;
  376. } else if( (char)0x80 <= a[i] && a[i] <= (char)0xFF ){
  377. // for 2 Byte Word
  378. saacproto.escapework[c++] = a[i++];
  379. saacproto.escapework[c++] = a[i];
  380. } else if( a[i] == '\' ){
  381. if( a[i+1] == 'S' ){     /* space */
  382. saacproto.escapework[c++] = ' ';
  383. } else if( a[i+1] == 'n' ){
  384. saacproto.escapework[c++] = 'n';
  385. } else if( a[i+1] == 'r' ){
  386. saacproto.escapework[c++] = 'r';
  387. } else if( a[i+1] == '\' ){
  388. saacproto.escapework[c++] = '\';
  389. } else {
  390. saacproto.escapework[c++] = a[i];
  391. }
  392. i++;           
  393. } else {
  394. saacproto.escapework[c++] = a[i];
  395. }
  396. }
  397. return saacproto.escapework;
  398. }
  399. /*
  400.    This function works only when char*src is escaped
  401.    NOTICE: Effects and Modifies the contents of char*src!
  402.    NOTICE : Ends the output token list with NULL pointer
  403. Ex:
  404.         v out[0]       v out[1]
  405.   "     asdjfhasfdasdf asdf asf asdf "
  406.  */
  407. #ifdef saacproto__ENCRYPT
  408. static void saacproto_decodeString( char *src , char *out );
  409. static void saacproto_encodeString( char *src , char *out , int maxoutlen );
  410. #endif
  411. void saacproto_splitString( char *src  )
  412. {
  413. int i,c=0;
  414. char *decoded;
  415. #ifdef saacproto__ENCRYPT
  416. decoded = saacproto.cryptwork;
  417. saacproto_decodeString( src , decoded );
  418. #else
  419. decoded = src;
  420. #endif
  421. if( saacproto_readlogfilename[0] != ''){
  422. FILE *rfp;
  423. rfp = fopen( saacproto_readlogfilename , "a+" );
  424. if(rfp)fprintf( rfp, "%sn",decoded );
  425. if(rfp)fclose(rfp);
  426. }
  427. for(i = 0 ; ; i++ ){
  428. if( decoded[i] == '' ) break;
  429. if( i==0){
  430.     saacproto.token_list[c++]=&(decoded[i]);
  431. }
  432. if( decoded[i]== ' '){
  433.     saacproto.token_list[c++]=&(decoded[i+1]);
  434. }
  435. }
  436. while( *decoded ){
  437. if( ( *decoded  ) == ' ' || (*decoded ) == 'n' || (*decoded ) == 'r' ) *decoded = '';
  438. decoded++;
  439.   }
  440. saacproto.token_list[c] = (char*)NULL;
  441. }
  442. int saacproto_default_write_wrap( int fd , char *buf , int size )
  443. {
  444. #ifndef WIN32
  445. return write( fd , buf , size );
  446. #else
  447. return 0;
  448. #endif
  449. }
  450. void saacproto_consumeLine(char *buf , int offset )
  451. {
  452. int i;
  453. int shift=0;
  454. buf+= offset;
  455. for(i=0;;i++){
  456. if( buf[i] == 'n' ){
  457. shift = i + 1;
  458. break;
  459. }
  460. }
  461.     if( shift == 0 )return;
  462. for(i=shift;;i++){
  463. buf[i - shift] = buf[i];
  464. if( buf[i] == '')break;
  465. }
  466. }
  467. void saacproto_copyLine( char*src , char *out , int outlen )
  468. {
  469. int i;
  470. for(i=0;;i++){
  471. out[i] = src[i];
  472. if( src[i] == 'n' ){
  473. out[i+1] = '' ;
  474. return;
  475. }
  476. if( src[i] == '' )return;
  477. }
  478. saacproto_strcpysafe( out , "" , outlen );
  479. }
  480. unsigned int saacproto_GetNewMessageID(void)
  481. {
  482. return saacproto.message_id++;
  483. }
  484. /*****************
  485.   WRITE
  486.    int flg : if 1, actually write. Otherwise no Network access
  487. *****************/
  488. void saacproto_DebugSend( int fd , char *msg )
  489. {
  490. saacproto_Send( fd, msg );
  491. }
  492. void saacproto_Send( int fd , char *msg )
  493. {
  494.     char *encoded;
  495. if( saacproto_writelogfilename[0] != '' ){
  496. FILE *wfp = fopen( saacproto_writelogfilename , "a+" );
  497. if(wfp)fprintf( wfp , "%sn", msg );
  498. if(wfp)fclose(wfp);
  499. }
  500. #ifdef saacproto__ENCRYPT
  501.     encoded = saacproto.cryptwork;
  502.     saacproto_encodeString( msg , encoded , saacproto.workbufsize*3 );
  503. #else
  504.     encoded = msg;
  505. #endif
  506. {
  507. /* add a newline character*/
  508. unsigned int l = strlen( encoded );
  509. if( l < saacproto.workbufsize *3){
  510. encoded[l] = 'n';
  511. encoded[l+1] = 0;
  512. l++;
  513. }else{
  514. //andy_log
  515. log( "l:%d < workbufsize:%d err : n (%s)n", l, saacproto.workbufsize, msg );
  516. }
  517. saacproto.write_func( fd , encoded , l);
  518. }
  519. }
  520. /****************
  521.   create a header which has function name and new Message ID
  522. ****************/
  523. void saacproto_CreateHeader( char *out ,char *fname )
  524. {
  525. sprintf( out ,"%u %s " , saacproto_GetNewMessageID() , fname );
  526. }
  527. void saacproto_CreateHeaderID( char *out,unsigned long msgid , char *fname )
  528. {
  529. sprintf( out ,"%u %s " , (unsigned int)msgid , fname );
  530. }
  531. char *saacproto_Ltoa( long v )
  532. {
  533. static char _ltoa_out[64];
  534. saacproto_cnv10to62( (int)v , _ltoa_out , sizeof( _ltoa_out ));
  535. /* sprintf( _ltoa_out , "%d" , (int)v );*/
  536. return _ltoa_out;
  537. }
  538. char *saacproto_Ultoa( unsigned long v )
  539. {
  540. static char _ultoa_out[64];
  541. sprintf( _ultoa_out , "%u" , (unsigned int)v );
  542. return _ultoa_out;
  543. }
  544. /****************
  545.    string address wrapper
  546. ****************/
  547. char *saacproto_wrapStringAddr( char *copy , int maxcopylen , char*src )
  548. {
  549. saacproto_strcpysafe( copy , src , maxcopylen );
  550. return copy;
  551. }
  552. /***************
  553.  bzero buffer ( some OSs like win32 don't have bzero )
  554. ***************/
  555. void saacproto_bzero( char *b , int siz )
  556. {
  557. unsigned int i;
  558. int *p;
  559. p = (int*)b;
  560. for(i=0;i<siz/sizeof(int);i++) {
  561. *(p+i)=0;
  562. }
  563. for(i=0;i<siz%sizeof(int);i++) {
  564. *(b+siz-1-i)=0;
  565. }
  566. }
  567. /***************
  568.     copy buffer
  569. ***************/
  570. void saacproto_bcopy(char*s , char *d , int siz )
  571. {
  572.     unsigned int i;
  573.     int *ps,*pd;
  574.     ps = (int*)s;
  575.     pd = (int*)d;
  576.     for(i=0;i<siz/sizeof(int);i++) {
  577.         *(pd+i) = *(ps+i);
  578.     }
  579.     for(i=0;i<siz%sizeof(int);i++) {
  580.         *(d+siz-1-i)=*(s+siz-1-i);
  581.     }
  582. }
  583. #ifdef saacproto__ENCRYPT
  584. /* define function body only if the macro is set( but it's default) */
  585. static void saacproto_encode64( unsigned char *in , int i, unsigned char *out );
  586. static int saacproto_decode64( unsigned char *in , unsigned char *out );
  587. static void saacproto_jDecode(char *src,int srclen,int key,char *decoded,int *decodedlen);
  588. static void saacproto_jEncode(char *src,int srclen,int key,char *encoded,int *encodedlen,int maxencodedlen);
  589. #define JENCODE_KEY    1000 
  590. /* translate original lsrpc text to code64 text */
  591. static void saacproto_encodeString( char *src , char *out , int maxoutlen )
  592. {
  593.     int jencodedlen=0;
  594.     long compressed_l = 0;
  595. int srclen = strlen( src ) + 1;
  596.     int flag=srclen;
  597. if( srclen < 100 ){
  598. if( (int)srclen > (int)( saacproto.workbufsize*3-2) ){
  599. fprintf( stderr, "lsgen: badly configured work buflenn" );
  600. exit(1);
  601. }
  602. if( (flag%2) == 1 ) flag ++;
  603. saacproto.compresswork[0] = flag;
  604. memcpy( saacproto.compresswork+1,src,srclen );
  605. compressed_l = srclen + 1;
  606. } else {
  607. if((flag%2)==0)flag++;
  608. saacproto.compresswork[0] = flag;
  609.         compressed_l = saacproto_ringoCompressor(
  610.             (unsigned char*)saacproto.compresswork + 1 ,
  611.     (long)saacproto.workbufsize*3 - 1,
  612.             (unsigned char*)src ,
  613.            (long)strlen(src) ) + 1;    /* be careful! */
  614. }
  615. /* return empty line if error or buffer excess */
  616. if( compressed_l <= 0 ){
  617. saacproto_strcpysafe( out , "n" , maxoutlen );
  618. return;
  619. }
  620.     memcpy( saacproto.jencodecopy ,saacproto.compresswork ,compressed_l );
  621.     saacproto_jEncode( saacproto.jencodecopy , compressed_l , JENCODE_KEY ,
  622.     saacproto.jencodeout, &jencodedlen , saacproto.workbufsize*3 -1 );
  623.     saacproto_encode64( (unsigned char*)saacproto.jencodeout , jencodedlen,  (unsigned char*)out );
  624. }
  625. /* translate code64 text to original lsrpc text */
  626. static void saacproto_decodeString( char *src , char *out )
  627. {
  628.     int compressed_l =0, outlen64;
  629.     int l;
  630.     long decompressed_l = 0;
  631.     /* copy src to copybuffer because jencoder modifies the input buffer */
  632.     l = strlen( src );
  633.     if( src[l-1]=='n' || src[l-1]=='r' )src[l-1]=0;
  634.     if( src[l-2]=='n' || src[l-2]=='r' )src[l-2]=0;
  635.     outlen64 = saacproto_decode64( (unsigned char*)src , (unsigned char*)saacproto.jencodecopy );
  636.     saacproto_jDecode( saacproto.jencodecopy , outlen64 , JENCODE_KEY,
  637. saacproto.compresswork , &compressed_l);
  638.     /*out[outlen]=0;  PENDING*/
  639.     if( (saacproto.compresswork[0] % 2 ) == 0 ){
  640.     if( compressed_l <= 0 ){
  641. decompressed_l = 0;
  642. fprintf( stderr, "LSRPC: too short:[%s]n", src );
  643. } else {
  644. memcpy( out, saacproto.compresswork+1, compressed_l -1 );
  645. decompressed_l = compressed_l -1;
  646. }
  647. } else {
  648.         decompressed_l =
  649. saacproto_ringoDecompressor( (unsigned char*)out ,
  650.                    (long)saacproto.workbufsize ,
  651. (unsigned char*)saacproto.compresswork+1 ,
  652. (long)compressed_l -1 );
  653. }
  654.     out[decompressed_l] = 0;
  655. }
  656. /* followings are taken from code64.c */
  657. char saacproto_charset[64]={
  658.     'A','B','C','D',    'E','F','G','H',
  659.     'I','J','K','L',    'M','N','O','P',
  660.     'Q','R','S','T',    'U','V','W','X',
  661.     'Y','Z','a','b',    'c','d','e','f',
  662.     'g','h','i','j',    'k','l','m','n',
  663.     'o','p','q','r',    's','t','u','v',
  664.     'w','x','y','z',    '0','1','2','3',
  665.     '4','5','6','7',    '8','9','+','-'
  666. };
  667. char saacproto_reversecharset[256]={
  668.     0,0,0,0, 0,0,0,0,
  669.     0,0,0,0, 0,0,0,0,
  670.     0,0,0,0, 0,0,0,0,
  671.     0,0,0,0, 0,0,0,0,
  672.     0,0,0,0, 0,0,0,0,
  673.     0,0,0,62, 0,63,0,0,
  674.     52,53,54,55, 56,57,58,59,
  675.     60,61,0,0, 0,0,0,0,
  676.     0,0,1,2, 3,4,5,6,
  677.     7,8,9,10, 11,12,13,14,
  678.     15,16,17,18, 19,20,21,22,
  679.     23,24,25,0, 0,0,0,0,
  680.     0,26,27,28, 29,30,31,32,
  681.     33,34,35,36, 37,38,39,40,
  682.     41,42,43,44, 45,46,47,48,
  683.     49,50,51,0, 0,0,0,0,
  684.     0,0,0,0,  0,0,0,0,
  685.     0,0,0,0,  0,0,0,0,
  686.     0,0,0,0,  0,0,0,0,
  687.     0,0,0,0,  0,0,0,0,
  688.     0,0,0,0,  0,0,0,0,
  689.     0,0,0,0,  0,0,0,0,
  690.     0,0,0,0,  0,0,0,0,
  691.     0,0,0,0,  0,0,0,0,
  692.     0,0,0,0,  0,0,0,0,
  693.     0,0,0,0,  0,0,0,0,
  694.     0,0,0,0,  0,0,0,0,
  695.     0,0,0,0,  0,0,0,0,
  696.     0,0,0,0,  0,0,0,0,
  697.     0,0,0,0,  0,0,0,0,
  698.     0,0,0,0,  0,0,0,0,
  699.     0,0,0,0,  0,0,0,0
  700. };
  701. static void saacproto_encode64( unsigned char *in , int len , unsigned char *out )
  702. {
  703.     int i;
  704.     int use_bytes;
  705.     int address = 0;
  706.     out[0] = 0;
  707.     for(i=0;;i+=3){
  708.         unsigned char in1 , in2 , in3;
  709.         unsigned char out1 ,out2 , out3 , out4;
  710.         if( i >= len ) break;
  711.         if( i >= (len-1)){   /* the last letter ( to be thrown away ) */
  712.             in1 = in[i] & 0xff;
  713.             in2 = in3 = 0;
  714.             use_bytes = 2;
  715.         } else if( i >= (len-2)){ /* the last 2 letters ( process only 1 byte)*/
  716.             in1 = in[i] & 0xff;
  717.             in2 = in[i+1] & 0xff;
  718.             in3 = 0;
  719.             use_bytes = 3;
  720.         } else {                /* there are more or equal than 3 letters */
  721.             in1 = in[i] & 0xff;
  722.             in2 = in[i+1] & 0xff;
  723.             in3 = in[i+2] & 0xff;
  724.             use_bytes = 4;
  725.         }
  726.         out1 = ((in1 & 0xfc)>>2) & 0x3f;
  727.         out2 = ((in1 & 0x03)<<4) | ((( in2 & 0xf0)>>4)&0x0f);
  728.         out3 = ((in2 & 0x0f)<<2) | ((( in3 & 0xc0)>>6)&0x03);
  729.         out4 = (in3 & 0x3f );
  730.         if( use_bytes >= 2 ){
  731.             out[address++] = saacproto_charset[out1];
  732.             out[address++] = saacproto_charset[out2];
  733.             out[address]=0;
  734.         }
  735.         if( use_bytes >= 3 ){
  736.             out[address++] = saacproto_charset[out3];
  737.             out[address]=0;
  738.         }
  739.         if( use_bytes >= 4 ){
  740.             out[address++] = saacproto_charset[out4];
  741.             out[address]=0;
  742.         }
  743.     }
  744. }
  745. /*
  746.  * Decode it
  747.  * char *in : encoded ascii chars
  748.  * char *out : decoded(  output)
  749.  * return value : output byte count
  750.  * 
  751.  * note: no need to have bigger buffer. because output is to 
  752.  * be smaller than input string size 
  753.  */
  754. static int saacproto_decode64( unsigned char *in , unsigned char *out )
  755. {
  756.     unsigned char in1 , in2 , in3 , in4;
  757.     unsigned char out1 , out2 , out3;
  758.     int use_bytes;
  759.     int address= 0;
  760.     int i;
  761.     for(i=0;;i+=4 ){
  762.         if( in[i] == 0 ){
  763.             break;
  764.         } else if( in[i+1] == 0 ){   /* the last letter */
  765.             break;
  766.         } else if( in[i+2] == 0 ){   /* the last 2 letters */
  767.             in1 = saacproto_reversecharset[in[i]];
  768.             in2 = saacproto_reversecharset[in[i+1]];
  769.             in3 = in4 = 0;
  770.             use_bytes = 1;
  771.         } else if( in[i+3] == 0 ){   /* the last  3 letters */
  772.             in1 = saacproto_reversecharset[in[i]];
  773.             in2 = saacproto_reversecharset[in[i+1]];
  774.             in3 = saacproto_reversecharset[in[i+2]];
  775.             in4 = 0;
  776.             use_bytes = 2;
  777.         } else {   /* process 4 letters */
  778.             in1 = saacproto_reversecharset[in[i]];
  779.             in2 = saacproto_reversecharset[in[i+1]];
  780.             in3 = saacproto_reversecharset[in[i+2]];
  781.             in4 = saacproto_reversecharset[in[i+3]];
  782.             use_bytes = 3;
  783.         }
  784.         out1 =  (in1<<2) | (((in2 & 0x30)>>4)&0x0f) ;
  785.         out2 =  ((in2 & 0x0f )<<4) | ((( in3 & 0x3c)>>2)&0x0f);
  786.         out3 =  ( (in3 &0x03)<<6) |  ( in4 & 0x3f );
  787.         if( use_bytes >= 1 ){
  788.             out[address++] = out1;
  789.         }
  790.         if( use_bytes >= 2 ){
  791.             out[address++] = out2;
  792.         }
  793.         if( use_bytes >= 3 ){
  794.             out[address++] = out3;
  795.         }
  796.         if( use_bytes != 3 ){
  797.             break;
  798.         }
  799.     }
  800.     return address;
  801. }
  802. /* followings are taken from Jencode.c by jun */
  803. static void saacproto_jEncode(char *src,int srclen,int key,char *encoded,int *encodedlen,int maxencodedlen)
  804. {
  805. char sum=0;
  806. int i;
  807. if(srclen+1 > maxencodedlen){
  808. *encodedlen = maxencodedlen;
  809. for(i=0;i<(*encodedlen);i++)encoded[i] = src[i];
  810. }
  811. if(srclen+1 <= maxencodedlen){
  812. *encodedlen=srclen+1;
  813. for(i=0;i<srclen;i++){
  814. sum = sum + src[i];
  815. if(((key%7) == (i%5))||((key%2) == (i%2))) src[i] = ~src[i];
  816. }
  817. for(i=0;i<(*encodedlen);i++){
  818. if(abs((key%srclen)) > i) encoded[i] = src[i] + sum*((i*i)%3); 
  819. if(abs((key%srclen)) == i) encoded[i] = sum;
  820. if(abs((key%srclen)) < i) encoded[i] = src[i-1] + sum*((i*i)%7);
  821. }
  822. }
  823. }
  824. static void saacproto_jDecode(char *src,int srclen,int key,char *decoded,int *decodedlen)
  825. {
  826. char sum=0;
  827. int i;
  828. *decodedlen=srclen-1;
  829. if( *decodedlen == 0 ){
  830. return; /* return error if length is 0 */
  831. }
  832. sum = src[abs(key%(*decodedlen))];
  833. for(i=0;i<srclen;i++){
  834. if(abs((key%(*decodedlen))) > i) decoded[i] = src[i] - sum*((i*i)%3);
  835. if(abs((key%(*decodedlen))) < i) decoded[i-1] = src[i] - sum*((i*i)%7);
  836. }
  837. for(i=0;i<(*decodedlen);i++){
  838. if(((key%7) == (i%5))||((key%2) == (i%2)))decoded[i] = ~decoded[i];
  839. }
  840. }
  841. /*****************************************************************/
  842. /*       Compress / Decompress routine                           */
  843. /*****************************************************************/
  844. #define B00000000 0
  845. #define B00000001 1
  846. #define B00000010 2
  847. #define B00000011 3
  848. #define B00000100 4
  849. #define B00000101 5
  850. #define B00000110 6
  851. #define B00000111 7
  852. #define B00001000 8
  853. #define B00001001 9
  854. #define B00001010 10
  855. #define B00001011 11
  856. #define B00001100 12
  857. #define B00001101 13
  858. #define B00001110 14
  859. #define B00001111 15
  860. #define B00010000 16
  861. #define B00010001 17
  862. #define B00010010 18
  863. #define B00010011 19
  864. #define B00010100 20
  865. #define B00010101 21
  866. #define B00010110 22
  867. #define B00010111 23
  868. #define B00011000 24
  869. #define B00011001 25
  870. #define B00011010 26
  871. #define B00011011 27
  872. #define B00011100 28
  873. #define B00011101 29
  874. #define B00011110 30
  875. #define B00011111 31
  876. #define B00100000 32
  877. #define B00100001 33
  878. #define B00100010 34
  879. #define B00100011 35
  880. #define B00100100 36
  881. #define B00100101 37
  882. #define B00100110 38
  883. #define B00100111 39
  884. #define B00101000 40
  885. #define B00101001 41
  886. #define B00101010 42
  887. #define B00101011 43
  888. #define B00101100 44
  889. #define B00101101 45
  890. #define B00101110 46
  891. #define B00101111 47
  892. #define B00110000 48
  893. #define B00110001 49
  894. #define B00110010 50
  895. #define B00110011 51
  896. #define B00110100 52
  897. #define B00110101 53
  898. #define B00110110 54
  899. #define B00110111 55
  900. #define B00111000 56
  901. #define B00111001 57
  902. #define B00111010 58
  903. #define B00111011 59
  904. #define B00111100 60
  905. #define B00111101 61
  906. #define B00111110 62
  907. #define B00111111 63
  908. #define B01000000 64
  909. #define B01000001 65
  910. #define B01000010 66
  911. #define B01000011 67
  912. #define B01000100 68
  913. #define B01000101 69
  914. #define B01000110 70
  915. #define B01000111 71
  916. #define B01001000 72
  917. #define B01001001 73
  918. #define B01001010 74
  919. #define B01001011 75
  920. #define B01001100 76
  921. #define B01001101 77
  922. #define B01001110 78
  923. #define B01001111 79
  924. #define B01010000 80
  925. #define B01010001 81
  926. #define B01010010 82
  927. #define B01010011 83
  928. #define B01010100 84
  929. #define B01010101 85
  930. #define B01010110 86
  931. #define B01010111 87
  932. #define B01011000 88
  933. #define B01011001 89
  934. #define B01011010 90
  935. #define B01011011 91
  936. #define B01011100 92
  937. #define B01011101 93
  938. #define B01011110 94
  939. #define B01011111 95
  940. #define B01100000 96
  941. #define B01100001 97
  942. #define B01100010 98
  943. #define B01100011 99
  944. #define B01100100 100
  945. #define B01100101 101
  946. #define B01100110 102
  947. #define B01100111 103
  948. #define B01101000 104
  949. #define B01101001 105
  950. #define B01101010 106
  951. #define B01101011 107
  952. #define B01101100 108
  953. #define B01101101 109
  954. #define B01101110 110
  955. #define B01101111 111
  956. #define B01110000 112
  957. #define B01110001 113
  958. #define B01110010 114
  959. #define B01110011 115
  960. #define B01110100 116
  961. #define B01110101 117
  962. #define B01110110 118
  963. #define B01110111 119
  964. #define B01111000 120
  965. #define B01111001 121
  966. #define B01111010 122
  967. #define B01111011 123
  968. #define B01111100 124
  969. #define B01111101 125
  970. #define B01111110 126
  971. #define B01111111 127
  972. #define B10000000 128
  973. #define B10000001 129
  974. #define B10000010 130
  975. #define B10000011 131
  976. #define B10000100 132
  977. #define B10000101 133
  978. #define B10000110 134
  979. #define B10000111 135
  980. #define B10001000 136
  981. #define B10001001 137
  982. #define B10001010 138
  983. #define B10001011 139
  984. #define B10001100 140
  985. #define B10001101 141
  986. #define B10001110 142
  987. #define B10001111 143
  988. #define B10010000 144
  989. #define B10010001 145
  990. #define B10010010 146
  991. #define B10010011 147
  992. #define B10010100 148
  993. #define B10010101 149
  994. #define B10010110 150
  995. #define B10010111 151
  996. #define B10011000 152
  997. #define B10011001 153
  998. #define B10011010 154
  999. #define B10011011 155
  1000. #define B10011100 156
  1001. #define B10011101 157
  1002. #define B10011110 158
  1003. #define B10011111 159
  1004. #define B10100000 160
  1005. #define B10100001 161
  1006. #define B10100010 162
  1007. #define B10100011 163
  1008. #define B10100100 164
  1009. #define B10100101 165
  1010. #define B10100110 166
  1011. #define B10100111 167
  1012. #define B10101000 168
  1013. #define B10101001 169
  1014. #define B10101010 170
  1015. #define B10101011 171
  1016. #define B10101100 172
  1017. #define B10101101 173
  1018. #define B10101110 174
  1019. #define B10101111 175
  1020. #define B10110000 176
  1021. #define B10110001 177
  1022. #define B10110010 178
  1023. #define B10110011 179
  1024. #define B10110100 180
  1025. #define B10110101 181
  1026. #define B10110110 182
  1027. #define B10110111 183
  1028. #define B10111000 184
  1029. #define B10111001 185
  1030. #define B10111010 186
  1031. #define B10111011 187
  1032. #define B10111100 188
  1033. #define B10111101 189
  1034. #define B10111110 190
  1035. #define B10111111 191
  1036. #define B11000000 192
  1037. #define B11000001 193
  1038. #define B11000010 194
  1039. #define B11000011 195
  1040. #define B11000100 196
  1041. #define B11000101 197
  1042. #define B11000110 198
  1043. #define B11000111 199
  1044. #define B11001000 200
  1045. #define B11001001 201
  1046. #define B11001010 202
  1047. #define B11001011 203
  1048. #define B11001100 204
  1049. #define B11001101 205
  1050. #define B11001110 206
  1051. #define B11001111 207
  1052. #define B11010000 208
  1053. #define B11010001 209
  1054. #define B11010010 210
  1055. #define B11010011 211
  1056. #define B11010100 212
  1057. #define B11010101 213
  1058. #define B11010110 214
  1059. #define B11010111 215
  1060. #define B11011000 216
  1061. #define B11011001 217
  1062. #define B11011010 218
  1063. #define B11011011 219
  1064. #define B11011100 220
  1065. #define B11011101 221
  1066. #define B11011110 222
  1067. #define B11011111 223
  1068. #define B11100000 224
  1069. #define B11100001 225
  1070. #define B11100010 226
  1071. #define B11100011 227
  1072. #define B11100100 228
  1073. #define B11100101 229
  1074. #define B11100110 230
  1075. #define B11100111 231
  1076. #define B11101000 232
  1077. #define B11101001 233
  1078. #define B11101010 234
  1079. #define B11101011 235
  1080. #define B11101100 236
  1081. #define B11101101 237
  1082. #define B11101110 238
  1083. #define B11101111 239
  1084. #define B11110000 240
  1085. #define B11110001 241
  1086. #define B11110010 242
  1087. #define B11110011 243
  1088. #define B11110100 244
  1089. #define B11110101 245
  1090. #define B11110110 246
  1091. #define B11110111 247
  1092. #define B11111000 248
  1093. #define B11111001 249
  1094. #define B11111010 250
  1095. #define B11111011 251
  1096. #define B11111100 252
  1097. #define B11111101 253
  1098. #define B11111110 254
  1099. #define B11111111 255
  1100. /* masks for first byte ( write )*/
  1101. int  saacproto_modifymask_first[8][9]={
  1102.     {0, B00000001,B00000011,B00000111,B00001111,B00011111,B00111111,B01111111,B11111111},/* mod 0*/
  1103.     {0, B00000011,B00000111,B00001111,B00011111,B00111111,B01111111,B11111111,B11111111},/* mod 1*/
  1104.     {0, B00000111,B00001111,B00011111,B00111111,B01111111,B11111111,B11111111,B11111111},/* mod 2*/
  1105.     {0, B00001111,B00011111,B00111111,B01111111,B11111111,B11111111,B11111111,B11111111},/* mod 3*/
  1106.     {0, B00011111,B00111111,B01111111,B11111111,B11111111,B11111111,B11111111,B11111111},/* mod 4*/
  1107.     {0, B00111111,B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111},/* mod 5*/
  1108.     {0, B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111},/* mod 6*/
  1109.     {0, B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111},/* mod 7*/
  1110. };
  1111. /* masks for second byte ( write ) */
  1112. int saacproto_modifymask_second[8][9]={
  1113.     {0, B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000},/* mod 0 */
  1114.     {0, B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001},/* mod 1 */
  1115.     {0, B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B00000011},/* mod 2 */
  1116.     {0, B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B00000011,B00000111},/* mod 3 */
  1117.     {0, B00000000,B00000000,B00000000,B00000000,B00000001,B00000011,B00000111,B00001111},/* mod 4 */
  1118.     {0, B00000000,B00000000,B00000000,B00000001,B00000011,B00000111,B00001111,B00011111},/* mod 5 */
  1119.     {0, B00000000,B00000000,B00000001,B00000011,B00000111,B00001111,B00011111,B00111111},/* mod 6 */
  1120.     {0, B00000000,B00000001,B00000011,B00000111,B00001111,B00011111,B00111111,B01111111},/* mod 7 */
  1121. };
  1122. /*
  1123.  * used by bitstream routines
  1124.  */
  1125. int bitstream_maxbyte, bitstream_bitaddr ;
  1126. char *bitstream_buf;
  1127. /* initialize bitstream for output */
  1128. static int initOutputBitStream( char *buf ,int buflen)
  1129. {
  1130.     bitstream_bitaddr = 0;
  1131.     bitstream_maxbyte = buflen;
  1132.     bitstream_buf = buf;
  1133.     memset( buf,0, buflen);
  1134.     return 0;
  1135. }
  1136. /* initialize bitstream for input */
  1137. static int initInputBitStream( char *buf , int buflen)
  1138. {
  1139.     bitstream_bitaddr = 0;
  1140.     bitstream_maxbyte = buflen;
  1141.     bitstream_buf = buf;
  1142.     return 0;
  1143. }
  1144. /*
  1145.  * read from bit stream. used only from 1 bit to 8 bits
  1146.  * this is a base routine
  1147.  */
  1148. static unsigned int readInputBitStreamBody( int bwidth )
  1149. {
  1150.     int mod = bitstream_bitaddr % 8;
  1151.     int byteaddr = bitstream_bitaddr / 8;
  1152.     /* return if excess */
  1153.     if( byteaddr >= bitstream_maxbyte)return 0;
  1154.     if( bwidth >= 1 && bwidth <= 8){
  1155.         int b1 = (( bitstream_buf[byteaddr] & saacproto_modifymask_first[mod][bwidth] )>>mod);
  1156.         int b2 = (( bitstream_buf[byteaddr+1] & saacproto_modifymask_second[mod][bwidth])<<(8-mod));
  1157.         bitstream_bitaddr += bwidth;
  1158.         return  b1 | b2;
  1159.     } else {
  1160.         return 0;
  1161.     }
  1162. }
  1163. /*
  1164.  *  read from bit stream. used from 1 bit to 32 bits
  1165.  *
  1166.  */
  1167. static unsigned int readInputBitStream( int bwidth )
  1168. {
  1169.     if( bwidth <= 0 ){
  1170.         return 0;
  1171.     } else if( bwidth >= 1 && bwidth <= 8 ){
  1172.         return readInputBitStreamBody( bwidth );
  1173.     } else if( bwidth >= 9 && bwidth <= 16 ){
  1174.         unsigned int first = readInputBitStreamBody(8);
  1175.         unsigned int second = readInputBitStreamBody( bwidth-8);
  1176.         return first + (second << 8 );
  1177.     } else if( bwidth >= 17 && bwidth <= 24 ){
  1178.         unsigned int first = readInputBitStreamBody(8);
  1179.         unsigned int second = readInputBitStreamBody(8);
  1180.         unsigned int third = readInputBitStreamBody(bwidth-8);
  1181.         return first + ( second << 8 ) + ( third << 16 );
  1182.     } else if( bwidth >= 25 && bwidth <= 32 ){
  1183.         unsigned int first = readInputBitStreamBody(8);
  1184.         unsigned int second = readInputBitStreamBody(8);
  1185.         unsigned int third = readInputBitStreamBody(8);
  1186.         unsigned int forth = readInputBitStreamBody(bwidth-8);
  1187.         return first + ( second << 8 ) + ( third << 16 ) + ( forth << 24 );
  1188.     }
  1189. return 0;
  1190. }
  1191. /*
  1192.  * write to a bitstream. only used from 1 bit to 8 bits
  1193.  * this is a base routine.
  1194.  */
  1195. static int writeOutputBitStreamBody( int bwidth , unsigned char b)
  1196. {
  1197.     int mod = bitstream_bitaddr % 8;
  1198.     int byteaddr = bitstream_bitaddr / 8;
  1199.     /* return error if excess */
  1200.     if( bitstream_maxbyte <= (byteaddr+1)) return -1;
  1201.     bitstream_buf[byteaddr] &= saacproto_modifymask_first[mod][bwidth];
  1202.     bitstream_buf[byteaddr] |= (b << mod) & saacproto_modifymask_first[mod][bwidth];
  1203.     bitstream_buf[byteaddr+1] &= saacproto_modifymask_second[mod][bwidth];
  1204.     bitstream_buf[byteaddr+1] |= (b>>(8-mod))& saacproto_modifymask_second[mod][bwidth];
  1205.     bitstream_bitaddr += bwidth;
  1206.     return byteaddr+1;
  1207. }
  1208. /*
  1209.  * write to a bitstream. used from 1 bits to 32 bits
  1210.  * returns -1 if error or buffer excession
  1211.  */
  1212. static int writeOutputBitStream( int bwidth, unsigned int dat)
  1213. {
  1214.     int ret;
  1215.     if( bwidth <= 0){
  1216.         return -1;
  1217.     } else if( bwidth >= 1 && bwidth <= 8 ){
  1218.         if((ret=writeOutputBitStreamBody( bwidth , (unsigned char)dat))<0)return -1;
  1219.     } else if( bwidth > 8 && bwidth <= 16 ){
  1220.         if(writeOutputBitStreamBody( 8 , (unsigned char)(dat&0xff))<0)return -1;
  1221.         if((ret=writeOutputBitStreamBody( bwidth - 8 , ( unsigned char)((dat>>8)&0xff)))<0)return -1;
  1222.     } else if( bwidth > 16 && bwidth <= 24 ){
  1223.         if(writeOutputBitStreamBody( 8 , (unsigned char)(dat&0xff))<0)return -1;
  1224.         if(writeOutputBitStreamBody( 8 , (unsigned char)((dat>>8)&0xff))<0)return -1;
  1225.         if((ret=writeOutputBitStreamBody( bwidth-16,(unsigned char)((dat>>16)&0xff)))<0)return -1;
  1226.     } else if( bwidth > 24 && bwidth <= 32 ){
  1227.         if(writeOutputBitStreamBody( 8 , (unsigned char)(dat&0xff))<0)return -1;
  1228.         if(writeOutputBitStreamBody( 8 , (unsigned char)((dat>>8)&0xff))<0)return -1;
  1229.         if(writeOutputBitStreamBody( 8 , (unsigned char)((dat>>16)&0xff))<0)return -1;
  1230.         if((ret=writeOutputBitStreamBody( bwidth-24,(unsigned char)((dat>>24)&0xff)))<0)return -1;
  1231.     } else {
  1232.         return -1;
  1233.     }
  1234.     return ret;
  1235. }
  1236. #define CHAR_SIZE 256
  1237. #define NODE_SIZE 512
  1238. #define BITS_LEN 9          /* 9 bit lzw compression */
  1239. typedef struct {
  1240.     unsigned char chr;
  1241.     int parent;
  1242.     int brother;
  1243.     int child;
  1244. }NODE;
  1245. long saacproto_ringoCompressor( unsigned char *code , long codelen ,
  1246.             unsigned char *text , long textlen)
  1247. {
  1248.     NODE node[NODE_SIZE];
  1249.     int freeNode;        
  1250.     int w,k;        /* used in this algo */
  1251.     int textind;    /* index to text buffer */
  1252.     int i;
  1253.     int position = 0;   /* indicates the last byte of code buffer */
  1254.     if( textlen <= 0 ) return -1;
  1255.     initOutputBitStream((char*) code,codelen);
  1256.     /* fill characters ( 0 ~ 255 ) in the beggining part of
  1257.        Node list */
  1258.     for(i=0; i<= CHAR_SIZE; i++){
  1259.         node[i].chr = (unsigned char)i;
  1260.         node[i].brother = i + 1;
  1261.         node[i].parent = 0;
  1262.         node[i].child = 0;
  1263.     }
  1264.     node[CHAR_SIZE].brother = 0;
  1265.     freeNode = CHAR_SIZE + 1;
  1266.     w = text[0];
  1267.     textind = 1;
  1268.     while(1){
  1269.         int rv;
  1270.         if( textind >= textlen ){
  1271.             k = CHAR_SIZE;      /* indicates EOF */
  1272.         } else {
  1273.             k = text[textind];
  1274.         }
  1275.         /* search if pattern 'wk' is registered or not. */
  1276.         rv = node[w].child;
  1277.         while(1){
  1278.             if( rv <= 0 ) break;
  1279.             if( node[rv].chr == k ) break;
  1280.             rv = node[rv].brother;
  1281.         }
  1282.         if( rv > 0 ){
  1283.             /* found it */
  1284.             w = rv;
  1285.         } else {
  1286.             position = writeOutputBitStream( BITS_LEN ,w  );
  1287.             /* return if buffer excession  */
  1288.             if( position > codelen ) return -1;
  1289.             /* register pattern 'wk' in the dictionary */
  1290.             if( freeNode < NODE_SIZE ){
  1291.                 node[freeNode].parent = w;
  1292.                 node[freeNode].chr = k;
  1293.                 node[freeNode].brother = node[w].child;
  1294.                 node[freeNode].child = 0;
  1295.                 node[w].child = freeNode;
  1296.                 freeNode++;
  1297.             }
  1298.             w = k;
  1299.         }
  1300.         if( textind == ( textlen + 1 )  ) break;
  1301.         textind++;
  1302.     }
  1303.     return position;
  1304. }
  1305. /*
  1306.  * Decoder.
  1307.  * return -1 if buffer excession. Notice buffer text
  1308.  * is modified .
  1309.  */
  1310. long saacproto_ringoDecompressor( unsigned char *text , long textlen ,
  1311.             unsigned char *code , long codelen)
  1312. {
  1313.     NODE node[NODE_SIZE];
  1314.     int stack[NODE_SIZE];
  1315.     int sp;
  1316.     int freeNode;
  1317.     int len;
  1318.     int i;
  1319.     int k = 0;
  1320.     int w = 0;
  1321.     if( codelen <= 0 ) return -1;
  1322.     initInputBitStream( (char*)code , codelen );
  1323.     for(i=0;i<CHAR_SIZE;i++){
  1324.         node[i].chr = (unsigned char)i;
  1325.         node[i].brother = i+1;
  1326.         node[i].parent = 0;
  1327.         node[i].child = 0;
  1328.     }
  1329.     node[CHAR_SIZE].brother = 0;
  1330.     freeNode = CHAR_SIZE + 1;
  1331.     len=0;  /* index to text buffer */
  1332.     sp=0;   /* stack pointer */
  1333.     while(1){
  1334.         int rv = 0;
  1335.         rv = readInputBitStream( BITS_LEN );
  1336.         /* return OK if EOF */
  1337.         if( rv == CHAR_SIZE ) break;        
  1338.         if( rv >= freeNode ){
  1339.             stack[sp++] = k;            /* exception */
  1340.             if( sp >=( sizeof( stack ) /sizeof(stack[0] )) )return -1;   
  1341.             k = w;
  1342.         } else {
  1343.             k = rv;
  1344.         }
  1345.         while(k> CHAR_SIZE ){
  1346.             if( k >= (sizeof(node)/sizeof(node[0]))) return -1;
  1347.             stack[sp++] = node[k].chr;
  1348.             k = node[k].parent;
  1349.             if( sp >=( sizeof( stack ) /sizeof(stack[0] )) ) return -1;
  1350.         }
  1351.         stack[sp++] = k;
  1352.         if( sp >= ( sizeof( stack ) /sizeof(stack[0] )) ) return -1;
  1353.         /* output to text buffer from stack.*/
  1354.         while(sp){
  1355.             if( ++len > textlen ) return -1;
  1356.             *text++ = stack[--sp];
  1357.         }
  1358.         /* register the pattern 'wk'*/
  1359.         if( len > 1 && freeNode < NODE_SIZE ){
  1360.             node[freeNode].parent = w;
  1361.             node[freeNode].chr = k;
  1362.             if( w >= (sizeof(node)/sizeof(node[0])))return -1;
  1363.             node[freeNode].brother = node[w].child;
  1364.             node[freeNode].child = 0;
  1365.             node[w].child = freeNode;
  1366.             freeNode++;
  1367.         }
  1368.         w = rv;
  1369.     }
  1370.     return len;
  1371. }
  1372. #endif  /* ifdef saacproto__ENCRYPT */
  1373. /* Convert 62-base digits to 10 digits */
  1374. int saacproto_a62toi( char *a )
  1375. {
  1376. int ret = 0;
  1377. int minus ;
  1378. if( a[0] == '-' ){
  1379. minus = -1;
  1380.         a++;
  1381. } else {
  1382. minus = 1;
  1383. }
  1384. while( *a != '' )
  1385. {
  1386. ret *= 62;
  1387. if( '0' <= (*a) && (*a) <= '9' )
  1388. ret += (*a)-'0';
  1389. else
  1390. if( 'a' <= (*a) && (*a) <= 'z' )
  1391. ret += (*a)-'a'+10;
  1392. else
  1393. if( 'A' <= (*a) && (*a) <= 'Z' )
  1394. ret += (*a)-'A'+36;
  1395. else
  1396. return 0;
  1397. a++;
  1398. }
  1399. return ret * minus;
  1400. }
  1401. /*  Convert 10-base digits into 62-base digits. */
  1402. char *saacproto_cnv10to62( int a, char *out, int outlen )
  1403. {
  1404. int i, j;
  1405.     char    base[] = { "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
  1406.     int     tmp[64];
  1407.     int     src;
  1408.     int minus;
  1409. int baselen = sizeof( base)-1;
  1410.     if( a < 0 ){
  1411. minus = 1;
  1412. a *= -1;
  1413. } else {
  1414. minus = 0;
  1415. }
  1416.     /* special case */    
  1417.     if( a < baselen) {
  1418. if( minus ){
  1419. *(out) = '-';
  1420. *(out+1) = base[a];
  1421. *(out+2) = '';
  1422. return (out);
  1423. } else {
  1424. *out = base[a];
  1425. *(out+1) = '';
  1426. return( out);
  1427. }
  1428.     }
  1429.     src = a;
  1430.     for( i = 0; src >= baselen; i ++ ) {
  1431.         tmp[i] = src % baselen;
  1432.         src /= baselen;
  1433.     }
  1434.     i--;
  1435.     if( minus ){
  1436. *out = '-';
  1437.       *(out+1) = base[src];
  1438. for( j = 2; i >= 0; i --, j ++ ) {
  1439. if( j > outlen - 2 ) return NULL;
  1440. *(out+j) = base[tmp[i]];
  1441. }
  1442. } else {
  1443.       *out = base[src];
  1444. for( j = 1; i >= 0; i --, j ++ ) {
  1445. if( j > outlen - 2 ) return NULL;
  1446. *(out+j) = base[tmp[i]];
  1447. }
  1448. }
  1449. *(out+j) = '';
  1450.     return( out);
  1451. }