home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume28 / m0 / part02 / l_format.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-06  |  3.7 KB  |  172 lines

  1. /*
  2.     l_format.c
  3. */
  4. /*  Copyright (c) 1994 Christian F. Tschudin. All rights reserved.
  5.  
  6.     Distributed under the terms of the GNU General Public License
  7.     version 2 of june 1991 as published by the Free Software
  8.     Foundation, Inc.
  9.  
  10.              This file is part of M0.
  11.  
  12. M0 is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY.  No author or distributor accepts responsibility to anyone for
  14. the consequences of using it or for whether it serves any particular
  15. purpose or works at all, unless he says so in writing.  Refer to the GNU
  16. General Public License for full details. 
  17.  
  18. Everyone is granted permission to copy, modify and redistribute M0, but
  19. only under the conditions described in the GNU General Public License. 
  20. A copy of this license is supposed to have been given to you along with
  21. M0 so you can know your rights and responsibilities.  It should be in a
  22. file named LICENSE.  Among other things, the copyright notice and this
  23. notice must be preserved on all copies.  */
  24.  
  25. #include "l_proto.h"
  26. #include "hdr.h"
  27. #include "chksum.h"
  28.  
  29. static void
  30. make_header(byteptr p, byteptr q, uint clen, uint dlen)
  31. {
  32.     struct header_s *hdr = (struct header_s *) p;
  33.     uint len = 16 + clen;
  34.  
  35.     hdr->version = 0;
  36.     hdr->flags = 0;
  37.     memcpy(hdr->queue, (char*)q, 8);
  38.     hdr->codelen = clen;
  39. #ifdef LITTLE_ENDIAN
  40.     swap_int(&(hdr->codelen));
  41. #endif
  42.     if (dlen) {
  43.         hdr->flags |= 0x80;
  44.         hdr->datalen = dlen;
  45. #ifdef LITTLE_ENDIAN
  46.         swap_int(&(hdr->datalen));
  47. #endif
  48.         len += 4;
  49.     }
  50.     hdr->crc = crc_ccitt(p+2, len - 2);
  51. #ifdef LITTLE_ENDIAN
  52.     swap_short(&(hdr->crc));
  53. #endif
  54. }
  55.  
  56.  
  57. byteptr
  58. make_msgr(byteptr q, byteptr c, uint clen, byteptr d, uint dlen, uint *len)
  59. {
  60.     uint doffs;
  61.     byteptr m;
  62.  
  63.     if (d) {
  64.         doffs = 20 + 4 * ((clen+3)/4);
  65.         *len = doffs + dlen;
  66.     } else
  67.         *len = 16 + clen;
  68.     m = malloc(*len);
  69.     if (!m)
  70.         return 0;
  71.     if (d) {
  72.         memcpy((char*)(m+20), (char*)c, clen);
  73.         memcpy((char*)(m+doffs), (char*)d, dlen);
  74.         make_header(m, q, clen, dlen);
  75.     } else {
  76.         memcpy((char*)(m+16), (char*)c, clen);
  77.         make_header(m, q, clen, 0);
  78.     }
  79.     return m;
  80. }
  81.  
  82.  
  83. eindex
  84. make_msgr_str(mproc p, eindex q, eindex c, eindex d)
  85. {
  86.     uint len, clen, dlen, doffs;
  87.     byteptr m, key;
  88.  
  89.     q = desub(p,q);
  90.     key = eaddr(p,q)->V.nam.u.s;
  91.     clen = elen(p,c);
  92.  
  93.     if (d) {
  94.         dlen = elen(p,d);
  95.         doffs = 20 + 4 * ((clen+3)/4);
  96.         len = doffs + dlen;
  97.     } else
  98.         len = 16 + clen;
  99.     m = malloc(len);
  100.     if (!m)
  101.         return 0;
  102.     if (d) {
  103.         str_export(p, m+20, c, 0, clen);
  104.         str_export(p, m+doffs, d, 0, dlen);
  105.         make_header(m, key, clen, dlen);
  106.     } else {
  107.         str_export(p, m+16, c, 0, clen);
  108.         make_header(m, key, clen, 0);
  109.     }
  110.     return str_import(p, m, len, len);
  111. }
  112.  
  113.  
  114. /* msgr string m must not be shared, but contigious (no subtype) */
  115.  
  116. retcode
  117. decomp_msgr(mproc p, eindex m, eindex *q, eindex *c, eindex *d)
  118. {
  119.     eptr mp = eaddr(p,m);
  120.     struct header_s hdr;
  121.     uint hlen = sizeof(hdr), coffs, doffs;
  122.     byteptr s;
  123.  
  124.     if (eplen(mp) < 16)
  125.         return ERR_SHORT_MSGR;
  126.     s = mp->V.str.s;
  127.  
  128.     if (eplen(mp) < sizeof(hdr))
  129.         hlen = eplen(mp);
  130.     memcpy((char*)&hdr, (char*)s, hlen);
  131.  
  132.     if (hdr.version != 0 )
  133.         return ERR_MSGR_WRONG_VERSION;
  134.  
  135. #ifdef LITTLE_ENDIAN
  136.     swap_short(&(hdr.crc));
  137.     swap_int(&(hdr.codelen));
  138. #endif
  139.     coffs = 16;
  140.     if (hdr.flags & 0x80) {
  141. #ifdef LITTLE_ENDIAN
  142.         swap_int(&(hdr.datalen));
  143. #endif
  144.         coffs += 4;
  145.         doffs = coffs + 4*((hdr.codelen+3)/4);
  146.     } else
  147.         hdr.datalen = 0;
  148.  
  149.     if (coffs + hdr.codelen > eplen(mp))
  150.         return ERR_MSGR_CRC;
  151.  
  152.     if (crc_ccitt(s+2, coffs + hdr.codelen - 2) != hdr.crc )
  153.         return ERR_MSGR_CRC;
  154.  
  155.     epattr(mp) &= ~(A_EXECUTABLE | A_WRITE);
  156.     *q = key_add(hdr.queue);
  157.     *c = make_sub(p, m, coffs);
  158.     elen(p,*c) = hdr.codelen;
  159.     eattr(p,*c) &= ~A_WRITE;
  160.     if (hdr.datalen) {
  161.         *d = make_sub(p, m, doffs);
  162.         if (doffs+hdr.datalen <= eplen(mp))
  163.             elen(p,*d) = hdr.datalen;
  164.         else
  165.             elen(p,*d) = eplen(mp) - doffs;
  166.         eattr(p,*d) &= ~A_WRITE;
  167.     } else
  168.         *d = 0;
  169.  
  170.     return OK;
  171. }
  172.