home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / Programming / Source / WAIS / ir / transprt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-02  |  11.4 KB  |  459 lines

  1.  
  2. /* this is a krufty transport layer for comm mediums that can not handle
  3.  * all 8 bits of ascii.
  4.  * Written by Harry Morris, modified by brewster.
  5.  * Hexcode written by Steve Swartz
  6.  * 
  7.  */
  8.  
  9. /* to do
  10.  *
  11.  *  compression
  12.  *  encryption
  13.  */
  14.  
  15. /* change log:
  16.  * 7/7/90 -brewster
  17.  * merged arts and harry's changes 7/7/90 -brewster
  18.  *
  19.  * 11/6/90 -tracy
  20.  * shift 6 bytes starting from [ as IBM gateway program
  21.  * masks out characters [\]^` in input,
  22.  * append H and I to the function names corresponding to the
  23.  * oroginal coding and the modified one. 'I' indicates IBM. 
  24.  */
  25.  
  26. #include "transprt.h"
  27. #include "wmessage.h" 
  28. #include "ustubs.h"
  29.  
  30. /*---------------------------------------------------------------------*/
  31. static char alphaH[] = /* Must be 65 consecutive ascii characters */
  32.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop";
  33.  
  34.  
  35. /*---------------------------------------------------------------------*/
  36.  
  37. static void hexCodeH _AP((char* data,long* len));
  38.  
  39. static void
  40. hexCodeH(data,len)
  41. char* data;
  42. long* len;
  43. /* compose a message for sending over ascii terminal lines. Input is '*len'
  44.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  45.  *
  46.  * Encoding goes like this. Let capital letters represent bits:
  47.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  48.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  49.  *
  50.  * 1 byte at end: ABCDEFGH
  51.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  52.  *
  53.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  54.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  55.  */
  56. {
  57.   long i, j;
  58.   
  59.   switch (*len % 3)
  60.     {
  61.     case 2:
  62.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  63.       data[j]   = alphaH[64];
  64.       data[j-1] = alphaH[data[i-1] & 0x0f];
  65.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  66.       data[j-3] = alphaH[data[i-2] & 0x3F];
  67.       break;
  68.     case 1:
  69.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  70.       data[j]   = alphaH[64];
  71.       data[j-1] = alphaH[64];
  72.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2];
  73.       data[j-3] = alphaH[data[i-2] & 0x3F];
  74.       break;
  75.     default:
  76.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  77.       break;
  78.     }
  79.   
  80.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  81.     { 
  82.       data[j]   = alphaH[data[i] & 0x3F];
  83.       data[j-1] = alphaH[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  84.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  85.       data[j-3] = alphaH[data[i-2] & 0x3F];
  86.     }
  87. }
  88.  
  89. /*---------------------------------------------------------------------*/
  90.  
  91. static void hexDecodeH _AP((char* data,long* len));
  92.  
  93. static void
  94. hexDecodeH(data,len)
  95. char* data;
  96. long* len;
  97. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  98.  *  will always be divisble by 4. Output is the binary bytes that were 
  99.  *  encoded into 'data'.
  100.  *
  101.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  102.  *  from ascii data to the 'bX' values has to become more complicated than
  103.  *  data[] - alpha[0].
  104.  */
  105. {
  106.   unsigned char b0, b1, b2, b3;
  107.   long i, j;
  108.  
  109.   
  110.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  111.     {
  112.       b0 = (data[j-4] & 0x07F) - alphaH[0];
  113.       b1 = (data[j-3] & 0x07F) - alphaH[0];
  114.       b2 = (data[j-2] & 0x07F) - alphaH[0];
  115.       b3 = (data[j-1] & 0x07F) - alphaH[0];
  116.       data[i-3] = b0 | (b1 & 0x30) << 2;
  117.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  118.       data[i-1] = b3 | (b2 & 0x30) << 2;
  119.     }
  120.  
  121.   *len = *len/4 * 3 - 2;
  122.   b0 = (data[j-4] & 0x07F) - alphaH[0];
  123.   b1 = (data[j-3] & 0x07F) - alphaH[0];
  124.   b2 = (data[j-2] & 0x07F) - alphaH[0];
  125.   b3 = (data[j-1] & 0x07F) - alphaH[0];
  126.   data[i-3] = b0 | (b1 & 0x30) << 2;
  127.  
  128.   if (b2 != 64)    
  129.     {
  130.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  131.       (*len)++;
  132.     }
  133.  
  134.   if (b3 != 64)
  135.     {
  136.       data[i-1] = b3 | (b2 & 0x30) << 2;
  137.       (*len)++;
  138.     }
  139. }
  140.  
  141. /*---------------------------------------------------------------------*/
  142.  
  143. void
  144. transportCodeH(data,len)
  145. char* data;
  146. long* len;
  147. /* krufty serial line transport layer - encode in hex and append in cr */
  148. /* Now it also writes a wais packet header on to the front of the packet.
  149.  *   --art 
  150.  */
  151.   hexCodeH(data,len);
  152.   data[*len] = '\r';
  153.   data[*len + 1] = '\0';
  154.   *len += 1;
  155. }
  156.  
  157. /*---------------------------------------------------------------------*/
  158.  
  159. void
  160. transportDecodeH(data,len)
  161. char* data;
  162. long* len;
  163. /* decode above */
  164. /* This does not have to deal with the wais packet header since it has
  165.    been removed at the end of the read.  */
  166.   if (*len == 0)
  167.     return;
  168.     
  169.   *len -= 1;
  170.   hexDecodeH(data,len);
  171. }
  172.  
  173. /*---------------------------------------------------------------------
  174.  Below are the set of transport coding/decoding functions for clients
  175.  dialing through IBM to DowQuest. Unlike the above one that
  176.  uses 65 consecutive ASCII character for the coding/decoding table,
  177.  table entries after charcater 'Z' are shift 6 characters.
  178.  *--------------------------------------------------------------------*/ 
  179.  
  180. #define LAST_NON_SHIFT_CHAR 90
  181. #define SHIFT_OFFSET   6
  182.  
  183. static char alphaI[] = 
  184.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
  185.  
  186.  
  187. static void hexCodeI _AP((char* data,long* len));
  188.  
  189. static void
  190. hexCodeI(data,len)
  191. char* data;
  192. long* len;
  193. /* compose a message for sending over ascii terminal lines. Input is '*len'
  194.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  195.  *
  196.  * Encoding goes like this. Let capital letters represent bits:
  197.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  198.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  199.  *
  200.  * 1 byte at end: ABCDEFGH
  201.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  202.  *
  203.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  204.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  205.  */
  206. {
  207.   long i, j;
  208.   
  209.   switch (*len % 3)
  210.     {
  211.     case 2:
  212.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  213.       data[j]   = alphaI[64];
  214.       data[j-1] = alphaI[data[i-1] & 0x0f];
  215.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  216.       data[j-3] = alphaI[data[i-2] & 0x3F];
  217.       break;
  218.     case 1:
  219.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  220.       data[j]   = alphaI[64];
  221.       data[j-1] = alphaI[64];
  222.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2];
  223.       data[j-3] = alphaI[data[i-2] & 0x3F];
  224.       break;
  225.     default:
  226.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  227.       break;
  228.     }
  229.   
  230.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  231.     { 
  232.       data[j]   = alphaI[data[i] & 0x3F];
  233.       data[j-1] = alphaI[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  234.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  235.       data[j-3] = alphaI[data[i-2] & 0x3F];
  236.     }
  237. }
  238.  
  239. /*---------------------------------------------------------------------*/
  240.  
  241. static void hexDecodeI _AP((char* data,long * len));
  242.  
  243. static void
  244. hexDecodeI(data,len)
  245. char* data;
  246. long* len;
  247. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  248.  *  will always be divisble by 4. Output is the binary bytes that were 
  249.  *  encoded into 'data'.
  250.  *
  251.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  252.  *  from ascii data to the 'bX' values has to become more complicated than
  253.  *  data[] - alpha[0].
  254.  */
  255. {
  256.   unsigned char b0, b1, b2, b3;
  257.   long i, j;
  258.  
  259.   for ( i=0; i < *len ; i++ )
  260.     if ( data[i] > LAST_NON_SHIFT_CHAR ) data[i] -= SHIFT_OFFSET;
  261.   
  262.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  263.     {
  264.       b0 = (data[j-4] & 0x07F) - alphaI[0];
  265.       b1 = (data[j-3] & 0x07F) - alphaI[0];
  266.       b2 = (data[j-2] & 0x07F) - alphaI[0];
  267.       b3 = (data[j-1] & 0x07F) - alphaI[0];
  268.       data[i-3] = b0 | (b1 & 0x30) << 2;
  269.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  270.       data[i-1] = b3 | (b2 & 0x30) << 2;
  271.     }
  272.  
  273.   *len = *len/4 * 3 - 2;
  274.   b0 = (data[j-4] & 0x07F) - alphaI[0];
  275.   b1 = (data[j-3] & 0x07F) - alphaI[0];
  276.   b2 = (data[j-2] & 0x07F) - alphaI[0];
  277.   b3 = (data[j-1] & 0x07F) - alphaI[0];
  278.   data[i-3] = b0 | (b1 & 0x30) << 2;
  279.  
  280.   if (b2 != 64)    
  281.     {
  282.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  283.       (*len)++;
  284.     }
  285.  
  286.   if (b3 != 64)
  287.     {
  288.       data[i-1] = b3 | (b2 & 0x30) << 2;
  289.       (*len)++;
  290.     }
  291. }
  292.  
  293. /*---------------------------------------------------------------------*/
  294.  
  295. void
  296. transportCodeI(data,len)
  297. char* data;
  298. long* len;
  299. /* krufty serial line transport layer - encode in hex and append in cr */
  300. /* Now it also writes a wais packet header on to the front of the packet.
  301.  *   --art 
  302.  */
  303.   hexCodeI(data,len);
  304.   data[*len] = '\r';
  305.   data[*len + 1] = '\0';
  306.   *len += 1;
  307. }
  308.  
  309. /*---------------------------------------------------------------------*/
  310.  
  311. void
  312. transportDecodeI(data,len)
  313. char* data;
  314. long* len;
  315. /* decode above */
  316. /* This does not have to deal with the wais packet header since it has
  317.    been removed at the end of the read.  */
  318.   if (*len == 0)
  319.     return;
  320.     
  321.   *len -= 1;
  322.   hexDecodeI(data,len);
  323. }
  324.  
  325. /*---------------------------------------------------------------------*/
  326.  
  327.  
  328. #ifdef NOTDEFINED /* here for back compatibility */
  329.  
  330. static void hexCode _AP((char* data,long * len));
  331.  
  332. static void
  333. hexCode(data,len)
  334. char* data;
  335. long* len;
  336. /* compose a message for sending over ascii terminal lines.  The data is hex,
  337.  */
  338. { long i;
  339.   for (i = *len-1; i >= 0; i--)
  340.     { data[i*2+1] = (data[i]&0x0F) + 'a';
  341.       data[i*2] = ((data[i]>>4)&0x0F) + 'a';
  342.     }
  343.   data[*len*2] = '\0';
  344.   *len = *len * 2;
  345. }
  346.  
  347. /*---------------------------------------------------------------------------*/
  348.  
  349. static void hexDecode _AP((char* data,long * len));
  350.  
  351. static void
  352. hexDecode(data,len)
  353. char* data;
  354. long* len;
  355. /* converts a buffer full of dataLen bytes of hex in place into the
  356. equivalent binary form. len is filled with the actual number of binary bytes.
  357.  */
  358. { long i;
  359.   *len = *len / 2;
  360.   for (i = 0; i < *len; i++)
  361.     { long temp = 0;
  362.       temp = (data[i*2]-'a')<<4;
  363.       temp += data[i*2+1]-'a';
  364.       data[i] = (char)temp;
  365.     }
  366.   data[*len] = '\0';
  367. }
  368.  
  369. #endif /* def NOTDEFINED */
  370. /*---------------------------------------------------------------------------*/
  371.  
  372. boolean
  373. transportCode(encoding,data,len)
  374. long encoding;
  375. char* data;
  376. long* len;
  377. /* krufty serial line transport layer - encode in hex and add trailing nl */
  378. {
  379.   switch (encoding){
  380.   case NO_ENCODING:
  381.     /* do nothing */
  382.     return(true);
  383.   case HEX_ENCODING:
  384.     transportCodeH(data,len);
  385.     return(true);
  386.   case IBM_HEXCODING:
  387.     transportCodeI(data,len);
  388.     return(true);
  389.   default:
  390.     return(false);
  391.   }
  392. }
  393.  
  394. /*---------------------------------------------------------------------------*/
  395.  
  396. boolean
  397. transportDecode(encoding,data,len)
  398. long encoding;
  399. char* data;
  400. long* len;
  401. /* decode above */
  402. {
  403.   switch (encoding){
  404.   case NO_ENCODING:
  405.     /* do nothing */
  406.     return(true);
  407.   case HEX_ENCODING:
  408.     transportDecodeH(data,len);
  409.     return(true);
  410.   case IBM_HEXCODING:
  411.     transportDecodeI(data,len);
  412.     return(true);
  413.   default:
  414.     return(false);
  415.   }
  416. }
  417.  
  418. /*---------------------------------------------------------------------------*/
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425. #ifdef old /* from the bad old days */
  426.  
  427.  
  428. /*---------------------------------------------------------------------------*/
  429.  
  430. void
  431. transportCode(data,len)
  432. char* data;
  433. long* len;
  434. /* krufty serial line transport layer - encode in hex and add trailing nl */
  435. {
  436.   hexCode(data,len);
  437.   data[*len] = '\r';
  438.   data[*len+1] = '\0';
  439. }
  440.  
  441. /*---------------------------------------------------------------------------*/
  442.  
  443. void
  444. transportDecode(data,len)
  445. char* data;
  446. long* len;
  447. /* decode above */
  448. {
  449.   hexDecode(data,len);
  450. }
  451.  
  452. /*---------------------------------------------------------------------------*/
  453.  
  454. #endif /* old */
  455.