/* "decode.c" ish for Human68 ken.Miyazaki & o.imaizumi 1987/12/05 OS9ext support 1988/02/01 same as OSK version. 1988/02/06 for Human68K. (Gigo) 1988/05/10 for UNIX (kondo) 1990/07/13 non-kana (keizo) */ #include #include #include #include #ifdef SysV #include #define index strchr #else #ifdef __TURBOC__ #include #include #define index strchr #else #include #endif #endif #include #include "ish.h" #define isleapyear(y) (((y)%4 == 0 && (y)%100 != 0 || (y)%400 == 0)) void hedprn(); struct tm tm; time_t timep[2], seconds(); int type,dline; unsigned char decbuf[LBUFLEN][LBUFLEN]; extern unsigned char *index(); extern int errno; decode() { int l, skip = 0,fc = 0; while((l = readln(ipath, buff, LBUFLEN)) > 0) { if (l > 60) { switch(*buff) { case '!': l = dec_jis7(buff, l); break; case '#': l = dec_jis8(buff, l); break; case '@': l = dec_sjis(buff, l); break; default: l = 0; break; } if (l > 60) { if (chkcrc(obuf, l)) { if (obuf[0] == '\0') { if (skip == 0) { fc++; hedprn(obuf); skip = decish(); } continue; } else { fprintf(stderr, "Can't Found Header\n"); skip = 0; continue; } } } } skip = 0; } /* EOF */ return(fc); } typedef struct { unsigned char sinc; unsigned char itype; unsigned char fsize[4]; unsigned char line[2]; unsigned short block; unsigned char byte; unsigned char ibyte; unsigned char iname[11]; unsigned char janle; unsigned char os; unsigned char exttype; unsigned char tstamp; unsigned char time[4]; unsigned char atr; /* 32: OS-9Ext only */ unsigned char ename[29]; /* 33-61: OS-9Ext only */ } ish_head; void hedprn(head) ish_head *head; { int i; unsigned char *p, *s; p = head->fsize; lsize = (long)p[0]+((long)p[1]<<8)+((long)p[2]<<16)+((long)p[3]<<24); p = head->line; jis = (long)p[0]+((long)p[1]<<8); type = head->ibyte; os = head->os; for(p = head->iname, s = name, i = 0; i < 8; i++) { *s++ = *p++; if (*p == ' ') break; } for(p = head->iname+8, i = 0; i < 3; i++) { if (*p == ' ') break; if (i == 0) *s++ = '.'; *s++ = *p++; } *s = '\0'; fprintf(stderr, "<<< %s from ",name); switch(os) { case MS_DOS: fprintf(stderr, "MS-DOS"); break; case CP_M: fprintf(stderr, "CP/M or MSX-DOS"); break; case OS_9: fprintf(stderr, "OS-9"); break; case OS_9EXT: fprintf(stderr, "OS-9Ext"); break; case UNIX: fprintf(stderr, "UNIX"); break; case OTHER: fprintf(stderr, "OTHER"); break; case ALL_OS : fprintf(stderr, "ALL-OS"); break; default: printf("?????"); } fprintf(stderr, " ( use "); switch(type) { case 13: fprintf(stderr, "jis7"); break; case 8: fprintf(stderr, "jis8"); break; case 14: fprintf(stderr, "shift_jis non-kana"); break; case 15: fprintf(stderr, "shift_jis"); break; } fprintf(stderr, " ) "); if (head->tstamp != 0) { p = head->time; tm.tm_year = (p[3]>>1)+80; tm.tm_mon = (p[3]&0x01)<<3; tm.tm_mon += (p[2]>>5) - 1; tm.tm_mday = p[2]&0x1f; tm.tm_hour = p[1]>>3; tm.tm_min = (p[1]&0x07)<<3; tm.tm_min += p[0]>>5; tm.tm_sec = (p[0]&0x1f)<<1; fprintf(stderr,"%02d/%02d/%02d %02d:%02d:%02d ", tm.tm_year,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec); #ifdef __TURBOC__ memcpy( &timep[0], head->time, 4); timep[1] = timep[0]; #else timep[0] = timep[1] = seconds(&tm); #endif } fprintf(stderr, "%ld byte >>>\n", lsize); switch(type) { /* 90-7-13 */ case 13: edmode = JIS7; break; case 8: edmode = JIS8; break; case 14: edmode = NJIS; break; case 15: edmode = SJIS; break; } } decish() { int fp, i, j; unsigned char *p; unsigned short crc, ncrc; if (access(name,0) == 0) { switch(mode) { case RESASK: fprintf(stderr, "'%s' already exist. replace ? (y/[n]/q):", name); fflush(stderr); if (read(0, buff, LBUFLEN) <= 0) buff[0] = 'n'; buff[0] = isalpha(buff[0]) ? toupper(buff[0]) : buff[0]; if (buff[0] == 'Q') exit(0); if (buff[0] == 'Y') { if(unlink(name) != ERR) break; fprintf(stderr, "'%s' - can't replace.\n", name); } return -1; case RESNEW: fprintf(stderr, "'%s' - file already exist. Skip it.\n", name); return -1; case RESALL: i = 0; fprintf(stderr, "file name change '%s'", name); strcpy(buff, name); if(p = index(name, '.')) *p = NULL; do { sprintf(buff, "%s.%03d", name, i++); } while(access(buff,0) == 0); fprintf(stderr, " to '%s'\n", buff); strcpy(name, buff); break; } } umask(i = umask(022)); #ifdef __TURBOC__ if ((fp = _creat(name, 0x20)) == ERR) { #else if ((fp = creat(name, 0666&~i)) == ERR) { #endif fprintf(stderr, "ish: Can't open:%s\n", name); exit(errno); } crc = 0xffff; lsize += 2; dline = lsize/(jis-3) + 1; fprintf(stderr, "%s : ", name); while (lsize > 0) { if (decblk() != 0) fprintf(stderr, " Error!!\007\n"); fflush(stderr); for (i = 1; i < jis-2; ++i) { if (lsize < (jis-3)) j = lsize; else j = jis-3; lsize -= j; if (lsize >= 2) { crc = calcrc(&decbuf[i][1], j, crc); write(fp, &decbuf[i][1], j); } else if (lsize == 1) { crc = calcrc(&decbuf[i][1], j-1, crc); write(fp, &decbuf[i][1], j-1); ncrc = decbuf[i][j] << 8; } else { if (j >= 2) { if (j > 2) { crc = calcrc(&decbuf[i][1], j-2, crc); write(fp, &decbuf[i][1], j-2); } ncrc = decbuf[i][j-1] << 8 | unschr(decbuf[i][j]); } else { ncrc |= unschr(decbuf[i][1]); } break; } } } if ((crc=~crc) != ncrc) fprintf(stderr, " CRC Error : %04X(%04X)\007\n", crc, ncrc); else fprintf(stderr, " Finished.\n"); #ifdef __TURBOC__ setftime(fp, timep); close(fp); #else utime(name, timep); #endif return 0; } decblk() { static int seq = 0; /* for out of sequence check */ int i, j, k, n, err, bad[2]; /* reset decode buffer */ for (i = 0; i <= jis; decbuf[i++][0] = '\0'); if (seq) /* put back ln */ for (i=0; i < jis-2; i++) decbuf[seq][i] = obuf[i]; seq = 0; while ((i = readln(ipath, buff, LBUFLEN)) > 0) { if (i < 60) continue; if ((k = dec_j(buff, i)) < jis) continue; if (chkcrc(obuf,k) == 0) continue; if ((j = obuf[0]) > jis) continue; if (j < seq) { seq = j; break; } else { seq = j; for (n=0; n < jis-2; ++n) decbuf[j][n] = obuf[n]; if (j == jis){ seq = 0; break; } } } k = (dline < jis-3) ? dline : jis-3; dline -= k; if (i <= 0 && dline > 2) { fprintf(stderr, " Warning - unexpected end of file"); return -1; } for (i=1, err=0; i < jis-2; i++) { if (decbuf[i][0] == '\0') { decbuf[i][0] = i; for(j = 1; j < jis-2; decbuf[i][j++] = 0); if (i <= k) { if (err < 2) bad[err] = i; err++; } } } if (err == 0) { fprintf(stderr, "o"); return(0); } if (err <= 2) if (ecc(err, bad[0], bad[1]) == 0){ fprintf(stderr, "%d",err); return(0); } else err = 3; fprintf(stderr, "%d <- too many", err); return ERR; } dec_j(argv, len) unsigned char *argv; int len; { switch(type) { case 13: return dec_jis7(argv, len); case 8 : return dec_jis8(argv, len); case 14: return dec_njis(argv, len); case 15: return dec_sjis(argv, len); default: return 0; } } /* "ecc.c" ish for OS9/OSK Error collection routine 87/12/17,88/01/30 By Gigo (original idea by M.ishizuka) */ ecc(err, e1, e2) int err, e1, e2; { register unsigned sum; register int i, j, k, x; if (err == 1) { /* 1 line error correct (easy!) */ if (decbuf[jis-2][0] != '\0') { for (j = 1; j < jis-2; j++) { for(i=1, sum=0; i < jis-1; sum -= decbuf[i++][j]); decbuf[e1][j] = sum; } return 0; } e2 = jis-2; /* oh! checksum(V) error increase */ decbuf[e2][0] = e2; for(j = 1; j < jis-2; decbuf[e2][j++] = 0); } /* correct 2 line error */ if (decbuf[jis][0] == '\0') /* no checksum(T) line, give up */ return 3; /* calc hidden byte */ switch(edmode) { case JIS7: sum = 0x9d; break; case JIS8: case NJIS: sum = 0x1a; break; case SJIS: sum = 0x04; break; } for(j = 1; j < jis-2; j++) sum -= decbuf[jis][j]; decbuf[jis][0] = sum; /* clear & set */ for(j = 0; j < jis; j++) decbuf[jis-1][j] = 0; x = 0; for(k = 0; k < jis-3 ;k++) { /* search scanning pass */ if (x <= e1) /* use '?' oprater, clash !! Oops! */ j = jis-1-e1+x; else j = x-e1+1; /* travase */ for(i = 1, sum = 0;i <= jis ;j++, i++) { j=j % (jis-2); sum -= decbuf[i][j]; } decbuf[e2][x=((x+e2-e1)%(jis-2))] = sum; /* vartical checksum */ for(i=1, sum=0; i < jis-1; i++) sum -= decbuf[i][x]; decbuf[e1][x] = sum; } return 0; } int readln(ipath, buff, maxlen) FILE *ipath; int maxlen; char *buff; { int c, i; i = 0; while((c = fgetc(ipath)) != EOF && maxlen > i) { if((c > 0x1f) && (c != 0x7f)) { buff[i++] = c; } if ((c == '\n') && i) break; } buff[i] = NULL; return i; } #ifndef __TURBOC__ int days(t) struct tm *t; { int y = t->tm_year+1900-1, m = t->tm_mon, d = t->tm_mday-1; static unsigned short month[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; d += 365*y - 718685; /* (1970-1)*365 */ d += y/4 - 492; /* (1970-1)/4 */ d -= y/100 - 19; /* (1970-1)/100 */ d += (y++)/400 - 4; /* (1970-1)/400 */ d += (long)month[m]; if (isleapyear(y) && m > 1) d++; return d; } time_t seconds(t) struct tm *t; { long s; #ifdef SysV extern int timezone; #else struct timeval tv; struct timezone tz; int timezone; gettimeofday(&tv, &tz); timezone = tz.tz_minuteswest * 60; #endif s = (long)days(t)*86400+t->tm_hour*3600+t->tm_min*60+t->tm_sec; s += timezone; #ifdef DST t = localtime(&s); if (t->t_isdst) s -= 3600; #endif return s; } #endif