1 Received: from CU-ARPA.CS.CORNELL.EDU by loki.cs.cornell.edu (5.61/I-1.91f) 2 id AA25874; Wed, 18 Jul 90 12:02:22 -0400 3 Message-Id: <9007181320.AA24810 (a] cu-arpa.cs.cornell.edu> 4 Received: from CORNELLC.CIT.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.61+2/1.91d) 5 id AA24810; Wed, 18 Jul 90 09:20:21 -0400 6 Received: from CORNELLC by CORNELLC.cit.cornell.edu (IBM VM SMTP R1.2.1MX) with BSMTP id 6769; Wed, 18 Jul 90 09:18:46 EDT 7 Received: from CAS.BITNET (MAILER) by CORNELLC (Mailer R2.05X) with BSMTP id 8 5378; Wed, 18 Jul 90 09:18:38 EDT 9 From: swl26%CAS.BITNET (a] CORNELLC.cit.cornell.edu 10 Date: Wed, 18 Jul 1990 09:16 EDT 11 Subject: Re(2): diffs for mvs port of flex-2.3 12 In-Reply-To: Your message of Tue, 17 Jul 90 17:42:3 13 To: vern (a] cs.cornell.edu 14 15 Sorry about the trailing blank problem. It's farily common with data sent 16 through bitnet paths, but ever the optimist ... 17 18 >I think there should be an 'M' at the beginning of the second line. 19 20 This isn't a problem. I believe that the first byte of the line indicates 21 it's length (in some manner). 22 23 Rather than re-send the data, how about a uudecode that compensates for 24 the trailing blank problem? I manually mangled the uuencoded file and ran 25 the following decode, and it seemed to work. 26 27 #! /bin/sh 28 # This is a shell archive. Remove anything before this line, then feed it 29 # into a shell via "sh file" or similar. To overwrite existing files, 30 # type "sh file -c". 31 # The tool that generated this appeared in the comp.sources.unix newsgroup; 32 # send mail to comp-sources-unix (a] uunet.uu.net if you want that tool. 33 # If this archive is complete, you will see the following message at the end: 34 # "End of shell archive." 35 # Contents: uudecode.c 36 # Wrapped by swl26@swl26aws on Wed Jul 18 08:59:24 1990 37 PATH=/bin:/usr/bin:/usr/ucb ; export PATH 38 if test -f 'uudecode.c' -a "${1}" != "-c" ; then 39 echo shar: Will not clobber existing file \"'uudecode.c'\" 40 else 41 echo shar: Extracting \"'uudecode.c'\" \(6418 characters\) 42 sed "s/^X//" >'uudecode.c' <<'END_OF_FILE' 43 X/* #ifndef lint 44 Xstatic char sccsid[] = "@(#)uudecode.c 5.3-1 (Berkeley) 9/1/87"; 45 X#endif */ 46 X 47 X/* Written by Mark Horton */ 48 X/* Modified by ajr (Alan J Rosenthatl,flaps (a] utcsri.UUCP) to use checksums */ 49 X/* Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for 50 X compatibility */ 51 X/* Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to fix a misleading 52 X error message on the Amiga port, to fix a bug that prevented decoding 53 X certain files, to work even if trailing spaces have been removed from a 54 X file, to check the filesize (if present), to add some error checking, to 55 X loop for multiple decodes from a single file, and to handle common 56 X BITNET mangling. Also kludged around a missing string function in Aztec 57 X C */ 58 X 59 X/* 60 X * uudecode [input] 61 X * 62 X * Decode a file encoded with uuencode. WIll extract multiple encoded 63 X * modules from a single file. Can deal with most mangled files, including 64 X * BITNET. 65 X */ 66 X 67 X#include <stdio.h> 68 X#include <ctype.h> 69 X 70 X#ifdef AMIGA 71 X#define AMIGA_LATTICE /* Set for Amiga Lattice C */ 72 X#define MCH_AMIGA 73 X#define MPU68000 74 X#endif 75 X 76 X#ifdef unix 77 X#include <pwd.h> 78 X#include <sys/types.h> 79 X#include <sys/stat.h> 80 X#endif 81 X 82 X#define SUMSIZE 64 83 X#define DEC(c) (((c) - ' ') & 077) /* single character decode */ 84 X 85 Xmain(argc, argv) 86 Xchar **argv; 87 X{ 88 XFILE *in, *out; 89 Xint through_loop=0; /* Dejavu indicator */ 90 Xint mode; /* file's mode (from header) */ 91 Xlong filesize; /* theoretical file size (from header) */ 92 Xchar dest[128]; 93 Xchar buf[80]; 94 X 95 X#ifdef AMIGA_LATTICE 96 Xextern int Enable_Abort; 97 X Enable_Abort=1; 98 X#endif 99 X 100 X /* A filename can be specified to be uudecoded, or nothing can 101 X be specified, and the input will come from STDIN */ 102 X 103 X switch (argc) 104 X { 105 X case 1: 106 X in=stdin; 107 X break; 108 X 109 X case 2: 110 X if ((in = fopen(argv[1], "r")) == NULL) 111 X { 112 X fprintf(stderr, "ERROR: can't find %s\n", argv[1]); 113 X fprintf(stderr, "USAGE: uudecode [infile]\n"); 114 X exit(10); 115 X } 116 X break; 117 X 118 X default: 119 X fprintf(stderr, "USAGE: uudecode [infile]\n"); 120 X exit(11); 121 X break; 122 X } 123 X 124 X /* Loop through file, searching for headers. Decode anything with a 125 X header, complain if there where no headers. */ 126 X 127 Xfor (;;) 128 X{ 129 X /* search file for header line */ 130 X for (;;) 131 X { 132 X if (fgets(buf, sizeof buf, in) == NULL) 133 X { 134 X if (!through_loop) 135 X { 136 X fprintf(stderr, "ERROR: no `begin' line!\n"); 137 X exit(12); 138 X } 139 X else 140 X { 141 X exit(0); 142 X } 143 X } 144 X if (strncmp(buf, "begin ", 6) == 0) 145 X break; 146 X } 147 X sscanf(buf, "begin %o %s", &mode, dest); 148 X 149 X#ifdef unix 150 X /* handle ~user/file format */ 151 X if (dest[0] == '~') 152 X { 153 X char *sl; 154 X struct passwd *getpwnam(); 155 X char *index(); 156 X struct passwd *user; 157 X char dnbuf[100]; 158 X 159 X sl = index(dest, '/'); 160 X if (sl == NULL) 161 X { 162 X fprintf(stderr, "Illegal ~user\n"); 163 X exit(13); 164 X } 165 X *sl++ = 0; 166 X user = getpwnam(dest+1); 167 X if (user == NULL) 168 X { 169 X fprintf(stderr, "No such user as %s\n", dest); 170 X exit(14); 171 X } 172 X strcpy(dnbuf, user->pw_dir); 173 X strcat(dnbuf, "/"); 174 X strcat(dnbuf, sl); 175 X strcpy(dest, dnbuf); 176 X } 177 X#endif 178 X 179 X /* create output file */ 180 X if ((out = fopen(dest, "w")) == NULL) 181 X { 182 X fprintf(stderr, "ERROR: can't open output file %s\n", dest); 183 X exit(15); 184 X } 185 X#ifdef unix 186 X chmod(dest, mode); 187 X#endif 188 X 189 X decode(in, out, dest); 190 X 191 X if (fgets(buf, sizeof buf, in) == NULL || strncmp(buf,"end",3)) 192 X { /* don't be overly picky about newline ^ */ 193 X fprintf(stderr, "ERROR: no `end' line\n"); 194 X exit(16); 195 X } 196 X 197 X if (!(fgets(buf,sizeof buf,in) == NULL || strncmp(buf,"size ",3))) 198 X { 199 X sscanf(buf, "size %ld", &filesize); 200 X if (ftell(out) != filesize) 201 X { 202 X fprintf(stderr, "ERROR: file should have been %ld bytes long but was 203 X exit(17); 204 X } 205 X } 206 X through_loop = 1; 207 X} /* forever */ 208 X} /* main */ 209 X 210 X/* 211 X * Copy from in to out, decoding as you go. 212 X * If a return or newline is encountered too early in a line, it is 213 X * assumed that means that some editor has truncated trailing spaces. 214 X */ 215 Xdecode(in, out, dest) 216 XFILE *in; 217 XFILE *out; 218 Xchar *dest; 219 X{ 220 Xchar buf[81]; 221 Xchar *bp; 222 Xint nosum=0; 223 X#ifndef unix 224 Xextern errno; 225 X#endif 226 Xregister int j; 227 Xregister int n; 228 Xint checksum, line; 229 X 230 X for (line = 1; ; line++) /* for each input line */ 231 X { 232 X if (fgets(buf, sizeof buf, in) == NULL) 233 X { 234 X fprintf(stderr, "ERROR: input ended unexpectedly!\n"); 235 X exit(18); 236 X } 237 X 238 X /* Pad end of lines in case some editor truncated trailing 239 X spaces */ 240 X 241 X for (n=0;n<79;n++) /* search for first \r, \n or \000 */ 242 X { 243 X if (buf[n]=='\176') /* If BITNET made a twiddle, */ 244 X buf[n]='\136'; /* we make a caret */ 245 X if (buf[n]=='\r'||buf[n]=='\n'||buf[n]=='\000') 246 X break; 247 X } 248 X for (;n<79;n++) /* when found, fill rest of line with space */ 249 X { 250 X buf[n]=' '; 251 X } 252 X buf[79]=0; /* terminate new string */ 253 X 254 X checksum = 0; 255 X n = DEC(buf[0]); 256 X if (n <= 0) 257 X break; /* 0 bytes on a line?? Must be the last line */ 258 X 259 X bp = &buf[1]; 260 X 261 X /* FOUR input characters go into each THREE output charcters */ 262 X 263 X while (n >= 4) 264 X { 265 X j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; putc(j, out); checksum += j; 266 X j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; putc(j, out); checksum += j; 267 X j = DEC(bp[2]) << 6 | DEC(bp[3]); putc(j, out); checksum += j; 268 X checksum = checksum % SUMSIZE; 269 X bp += 4; 270 X n -= 3; 271 X } 272 X 273 X j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; 274 X checksum += j; 275 X if (n >= 1) 276 X putc(j, out); 277 X j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; 278 X checksum += j; 279 X if (n >= 2) 280 X putc(j, out); 281 X j = DEC(bp[2]) << 6 | DEC(bp[3]); 282 X checksum += j; 283 X if (n >= 3) 284 X putc(j, out); 285 X checksum = checksum % SUMSIZE; 286 X bp += 4; 287 X n -= 3; 288 X 289 X#ifndef unix 290 X /* Error checking under UNIX??? You must be kidding... */ 291 X /* Check if an error occured while writing to that last line */ 292 X if (errno) 293 X { 294 X fprintf(stderr, "ERROR: error writing to %s\n",dest); 295 X exit(19); 296 X } 297 X#endif 298 X 299 X /* The line has been decoded; now check that sum */ 300 X 301 X nosum |= !isspace(*bp); 302 X if (nosum) /* Is there a checksum at all?? */ 303 X { 304 X if (checksum != DEC(*bp)) /* Does that checksum match? */ 305 X { 306 X fprintf(stderr, "ERROR: checksum mismatch decoding %s, line %d.\ 307 X } 308 X } /* sum */ 309 X } /* line */ 310 X} /* function */ 311 X 312 X#ifdef unix 313 X/* 314 X * Return the ptr in sp at which the character c appears; 315 X * 0 if not found 316 X */ 317 Xchar * 318 Xindex(sp, c) 319 Xregister char *sp, c; 320 X{ 321 X do 322 X { 323 X if (*sp == c) 324 X return(sp); 325 X } 326 X while (*sp++); 327 X 328 X return(0); 329 X} 330 X#endif unix 331 X 332 333 END_OF_FILE 334 echo shar: NEWLINE appended to \"'uudecode.c'\" 335 if test 6419 -ne `wc -c <'uudecode.c'`; then 336 echo shar: \"'uudecode.c'\" unpacked with wrong size! 337 fi 338 # end of 'uudecode.c' 339 fi 340 echo shar: End of shell archive. 341 exit 0 342