17363955dSSøren Schmidt /*- 2*f76b3199SUlrich Spörlein * Copyright (c) 1994 Søren Schmidt 37363955dSSøren Schmidt * All rights reserved. 47363955dSSøren Schmidt * 57363955dSSøren Schmidt * Redistribution and use in source and binary forms, with or without 67363955dSSøren Schmidt * modification, are permitted provided that the following conditions 77363955dSSøren Schmidt * are met: 87363955dSSøren Schmidt * 1. Redistributions of source code must retain the above copyright 9a926a37bSSøren Schmidt * notice, this list of conditions and the following disclaimer, 10a926a37bSSøren Schmidt * in this position and unchanged. 117363955dSSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 127363955dSSøren Schmidt * notice, this list of conditions and the following disclaimer in the 137363955dSSøren Schmidt * documentation and/or other materials provided with the distribution. 147363955dSSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1521dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 167363955dSSøren Schmidt * 177363955dSSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 187363955dSSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 197363955dSSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 207363955dSSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 217363955dSSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 227363955dSSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237363955dSSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247363955dSSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257363955dSSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 267363955dSSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277363955dSSøren Schmidt */ 287363955dSSøren Schmidt 299396247eSPhilippe Charnier #ifndef lint 309396247eSPhilippe Charnier static const char rcsid[] = 3197d92980SPeter Wemm "$FreeBSD$"; 329396247eSPhilippe Charnier #endif /* not lint */ 339396247eSPhilippe Charnier 347363955dSSøren Schmidt #include <stdio.h> 35bfc214e3SBrian Somers #include <string.h> 36bfc214e3SBrian Somers #include "decode.h" 377363955dSSøren Schmidt 385e0db936SMaxim Sobolev int decode(FILE *fd, char *buffer, int len) 397363955dSSøren Schmidt { 405e0db936SMaxim Sobolev int n, pos = 0, tpos; 415e0db936SMaxim Sobolev char *bp, *p; 425e0db936SMaxim Sobolev char tbuffer[3]; 437363955dSSøren Schmidt char temp[128]; 447363955dSSøren Schmidt 457363955dSSøren Schmidt #define DEC(c) (((c) - ' ') & 0x3f) 467363955dSSøren Schmidt 477363955dSSøren Schmidt do { 487363955dSSøren Schmidt if (!fgets(temp, sizeof(temp), fd)) 497363955dSSøren Schmidt return(0); 507363955dSSøren Schmidt } while (strncmp(temp, "begin ", 6)); 519a03b27dSXin LI sscanf(temp, "begin %o %s", (unsigned *)&n, temp); 525e0db936SMaxim Sobolev bp = buffer; 537363955dSSøren Schmidt for (;;) { 547363955dSSøren Schmidt if (!fgets(p = temp, sizeof(temp), fd)) 557363955dSSøren Schmidt return(0); 567363955dSSøren Schmidt if ((n = DEC(*p)) <= 0) 577363955dSSøren Schmidt break; 585e0db936SMaxim Sobolev for (++p; n > 0; p += 4, n -= 3) { 595e0db936SMaxim Sobolev tpos = 0; 607363955dSSøren Schmidt if (n >= 3) { 615e0db936SMaxim Sobolev tbuffer[tpos++] = DEC(p[0])<<2 | DEC(p[1])>>4; 625e0db936SMaxim Sobolev tbuffer[tpos++] = DEC(p[1])<<4 | DEC(p[2])>>2; 635e0db936SMaxim Sobolev tbuffer[tpos++] = DEC(p[2])<<6 | DEC(p[3]); 647363955dSSøren Schmidt } 657363955dSSøren Schmidt else { 667363955dSSøren Schmidt if (n >= 1) { 675e0db936SMaxim Sobolev tbuffer[tpos++] = 687363955dSSøren Schmidt DEC(p[0])<<2 | DEC(p[1])>>4; 697363955dSSøren Schmidt } 707363955dSSøren Schmidt if (n >= 2) { 715e0db936SMaxim Sobolev tbuffer[tpos++] = 727363955dSSøren Schmidt DEC(p[1])<<4 | DEC(p[2])>>2; 737363955dSSøren Schmidt } 747363955dSSøren Schmidt if (n >= 3) { 755e0db936SMaxim Sobolev tbuffer[tpos++] = 767363955dSSøren Schmidt DEC(p[2])<<6 | DEC(p[3]); 777363955dSSøren Schmidt } 787363955dSSøren Schmidt } 795e0db936SMaxim Sobolev if (tpos == 0) 805e0db936SMaxim Sobolev continue; 815e0db936SMaxim Sobolev if (tpos + pos > len) { 825e0db936SMaxim Sobolev tpos = len - pos; 835e0db936SMaxim Sobolev /* 845e0db936SMaxim Sobolev * Arrange return value > len to indicate 855e0db936SMaxim Sobolev * overflow. 865e0db936SMaxim Sobolev */ 875e0db936SMaxim Sobolev pos++; 885e0db936SMaxim Sobolev } 895e0db936SMaxim Sobolev bcopy(tbuffer, bp, tpos); 905e0db936SMaxim Sobolev pos += tpos; 915e0db936SMaxim Sobolev bp += tpos; 925e0db936SMaxim Sobolev if (pos > len) 935e0db936SMaxim Sobolev return(pos); 945e0db936SMaxim Sobolev } 957363955dSSøren Schmidt } 967363955dSSøren Schmidt if (!fgets(temp, sizeof(temp), fd) || strcmp(temp, "end\n")) 977363955dSSøren Schmidt return(0); 987363955dSSøren Schmidt return(pos); 997363955dSSøren Schmidt } 100