home *** CD-ROM | disk | FTP | other *** search
- /*
- l_format.c
- */
- /* Copyright (c) 1994 Christian F. Tschudin. All rights reserved.
-
- Distributed under the terms of the GNU General Public License
- version 2 of june 1991 as published by the Free Software
- Foundation, Inc.
-
- This file is part of M0.
-
- M0 is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone for
- the consequences of using it or for whether it serves any particular
- purpose or works at all, unless he says so in writing. Refer to the GNU
- General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute M0, but
- only under the conditions described in the GNU General Public License.
- A copy of this license is supposed to have been given to you along with
- M0 so you can know your rights and responsibilities. It should be in a
- file named LICENSE. Among other things, the copyright notice and this
- notice must be preserved on all copies. */
-
- #include "l_proto.h"
- #include "hdr.h"
- #include "chksum.h"
-
- static void
- make_header(byteptr p, byteptr q, uint clen, uint dlen)
- {
- struct header_s *hdr = (struct header_s *) p;
- uint len = 16 + clen;
-
- hdr->version = 0;
- hdr->flags = 0;
- memcpy(hdr->queue, (char*)q, 8);
- hdr->codelen = clen;
- #ifdef LITTLE_ENDIAN
- swap_int(&(hdr->codelen));
- #endif
- if (dlen) {
- hdr->flags |= 0x80;
- hdr->datalen = dlen;
- #ifdef LITTLE_ENDIAN
- swap_int(&(hdr->datalen));
- #endif
- len += 4;
- }
- hdr->crc = crc_ccitt(p+2, len - 2);
- #ifdef LITTLE_ENDIAN
- swap_short(&(hdr->crc));
- #endif
- }
-
-
- byteptr
- make_msgr(byteptr q, byteptr c, uint clen, byteptr d, uint dlen, uint *len)
- {
- uint doffs;
- byteptr m;
-
- if (d) {
- doffs = 20 + 4 * ((clen+3)/4);
- *len = doffs + dlen;
- } else
- *len = 16 + clen;
- m = malloc(*len);
- if (!m)
- return 0;
- if (d) {
- memcpy((char*)(m+20), (char*)c, clen);
- memcpy((char*)(m+doffs), (char*)d, dlen);
- make_header(m, q, clen, dlen);
- } else {
- memcpy((char*)(m+16), (char*)c, clen);
- make_header(m, q, clen, 0);
- }
- return m;
- }
-
-
- eindex
- make_msgr_str(mproc p, eindex q, eindex c, eindex d)
- {
- uint len, clen, dlen, doffs;
- byteptr m, key;
-
- q = desub(p,q);
- key = eaddr(p,q)->V.nam.u.s;
- clen = elen(p,c);
-
- if (d) {
- dlen = elen(p,d);
- doffs = 20 + 4 * ((clen+3)/4);
- len = doffs + dlen;
- } else
- len = 16 + clen;
- m = malloc(len);
- if (!m)
- return 0;
- if (d) {
- str_export(p, m+20, c, 0, clen);
- str_export(p, m+doffs, d, 0, dlen);
- make_header(m, key, clen, dlen);
- } else {
- str_export(p, m+16, c, 0, clen);
- make_header(m, key, clen, 0);
- }
- return str_import(p, m, len, len);
- }
-
-
- /* msgr string m must not be shared, but contigious (no subtype) */
-
- retcode
- decomp_msgr(mproc p, eindex m, eindex *q, eindex *c, eindex *d)
- {
- eptr mp = eaddr(p,m);
- struct header_s hdr;
- uint hlen = sizeof(hdr), coffs, doffs;
- byteptr s;
-
- if (eplen(mp) < 16)
- return ERR_SHORT_MSGR;
- s = mp->V.str.s;
-
- if (eplen(mp) < sizeof(hdr))
- hlen = eplen(mp);
- memcpy((char*)&hdr, (char*)s, hlen);
-
- if (hdr.version != 0 )
- return ERR_MSGR_WRONG_VERSION;
-
- #ifdef LITTLE_ENDIAN
- swap_short(&(hdr.crc));
- swap_int(&(hdr.codelen));
- #endif
- coffs = 16;
- if (hdr.flags & 0x80) {
- #ifdef LITTLE_ENDIAN
- swap_int(&(hdr.datalen));
- #endif
- coffs += 4;
- doffs = coffs + 4*((hdr.codelen+3)/4);
- } else
- hdr.datalen = 0;
-
- if (coffs + hdr.codelen > eplen(mp))
- return ERR_MSGR_CRC;
-
- if (crc_ccitt(s+2, coffs + hdr.codelen - 2) != hdr.crc )
- return ERR_MSGR_CRC;
-
- epattr(mp) &= ~(A_EXECUTABLE | A_WRITE);
- *q = key_add(hdr.queue);
- *c = make_sub(p, m, coffs);
- elen(p,*c) = hdr.codelen;
- eattr(p,*c) &= ~A_WRITE;
- if (hdr.datalen) {
- *d = make_sub(p, m, doffs);
- if (doffs+hdr.datalen <= eplen(mp))
- elen(p,*d) = hdr.datalen;
- else
- elen(p,*d) = eplen(mp) - doffs;
- eattr(p,*d) &= ~A_WRITE;
- } else
- *d = 0;
-
- return OK;
- }
-