#include #include #include /* this function decides if this is a Prime text file or binary file by checking the contents of the first tape buffer. The conditions for a text file are: - it can't be inside a segdir (checked before calling here) - it has to be a SAM or DAM file - COMO files are DAM files :( - it has to have at least 1 newline in the first buffer, usually 4090+ bytes; text files with an initial line longer than this have to be converted after the restore using ptextu - lines have to start on word boundaries, with zero padding after nl (NOTE: como files have space padding, so allow that too) - only text characters, nl, ff, :001 at the beginning of a line, :221 (compression) and :211 (tab) are allowed in text files */ /* max length of extension including . and ending null byte */ #define MAXEXTENSION 10 static struct { char ext[MAXEXTENSION]; int ftype; } exttype[] = { {".basic", 1}, {".cbl", 1}, {".c", 1}, {".cc", 1}, {".ci", 1}, {".cobol", 1}, {".comi", 1}, {".como", 1}, {".cpl", 1}, {".f77", 1}, {".ftn", 1}, {".ibas", 1}, {".ins", 1}, {".list", 1}, {".map", 1}, {".mod", 1}, {".pascal", 1}, {".plp", 1}, {".pl1", 1}, {".pl1g", 1}, {".pma", 1}, {".rpg", 1}, {".runi", 1}, {".runo", 1}, {".spl", 1}, {".sr", 1}, {".vrpg", 1}, {".bin", 0}, {".dl", 0}, {".save", 0}, }; #define EXTENTRIES sizeof(exttype)/sizeof(exttype[0]) int isptext(char *path, int filetype, unsigned char *buf, int len) { int i, hasnl, skipline; unsigned char ch; unsigned char extension[MAXEXTENSION]; /* scan backward to get file extension */ extension[0] = 0; for (i=strlen(path)-1; i >= 0; i--) if (path[i] == '.') { strncpy(extension, path+i, sizeof(extension)-1); break; } if (extension[0] == '.') for (i=0; i < EXTENTRIES; i++) if (strcasecmp(extension, exttype[i].ext) == 0) return exttype[i].ftype; if (filetype == 0 || (filetype == 1 && strcasecmp(extension,".como") == 0)) ; else { #ifdef DEBUG fprintf(stderr, "Filetype %d can't be a text file\n", filetype); #endif return 0; } hasnl = 0; skipline = 0; for (i=0; i= OBUFMAX) { if (fd != -1) if (write(fd, obuf, n) != n) { fprintf(stderr,"File write error text conversion, n=%d\n", n); exit(1); } n = 0; } } if (n > 0 && fd != -1 && write(fd, obuf, n) != n) { fprintf(stderr,"File write error text conversion, n=%d\n", n); exit(1); } return len; } /* scans buffer contents to see if it qualifies as a Unix text file that should be converted to Prime text. Text files can only have: - printable ASCII characters - tab - newline - carriage return - form feed */ int isutext(char *path, unsigned char *buf, int len) { int i, hasnl, skipline; unsigned char ch; unsigned char extension[MAXEXTENSION]; /* scan backward to get file extension */ extension[0] = 0; for (i=strlen(path)-1; i >= 0; i--) if (path[i] == '.') { strncpy(extension, path+i, sizeof(extension)-1); break; } if (extension[0] == '.') for (i=0; i < EXTENTRIES; i++) if (strcasecmp(extension, exttype[i].ext) == 0) return exttype[i].ftype; /* extension didn't determine type; check file contents */ hasnl = 0; for (i=0; ioddbyte = 0; state->col = 0; state->spaces = 0; It's possible that a string of spaces could be lost at the end of the file, but this is very unlikely since text files are supposed to end with a newline. */ int utextp(unsigned char *buf, int len, utextp_t *state) { int i, n, nsp; unsigned char ch; n = 0; /* next output buffer position */ for (i=0; ispaces++; else if (ch == '\t') { nsp = 8 - (state->col & 7); state->spaces += nsp; state->col += nsp; } else { while (state->spaces) { /* dump held-up spaces for non-space */ if (state->spaces < 3) { state->obuf[n++] = 0240; state->spaces--; state->oddbyte = ~state->oddbyte; } else { nsp = state->spaces; if (nsp > 255) /* can only handle 255 at once! */ nsp = 255; state->obuf[n++] = 0221; state->obuf[n++] = nsp; state->spaces = state->spaces - nsp; } } if (ch == '\r') /* ignore carriage returns (Windoze) */ continue; state->obuf[n++] = ch | 0x80; if (ch == 0212 && !state->oddbyte) state->obuf[n++] = 0; /* pad line to a word boundary */ else state->oddbyte = ~state->oddbyte; } if (n >= OBUFMAX) { if (fd != -1) if (write(fd, state->obuf, n) != n) { fprintf(stderr,"File write error text conversion, n=%d\n", n); exit(1); } n = 0; } } if (n > 0 && fd != -1 && write(fd, state->obuf, n) != n) { fprintf(stderr,"File write error text conversion, n=%d\n", n); exit(1); } return len; } #endif /* converts a fixed-length string in place from Prime to regular ascii */ void pasciiu(char *p, int len) { int i; for (i=0; i