source: trunk/athena/bin/ansi/ansi.c @ 6

Revision 6, 10.5 KB checked in by builder, 39 years ago (diff)
Initial revision
Line 
1/*
2 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/ansi/ansi.c,v $
3 *      $Author: builder $
4 *      $Locker:  $
5 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/ansi/ansi.c,v 1.1 1985-04-12 15:28:23 builder Exp $
6 */
7
8#ifndef lint
9static char *rcsid_ansi_c = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/ansi/ansi.c,v 1.1 1985-04-12 15:28:23 builder Exp $";
10#endif  lint
11
12#include <stdio.h>
13/* Rewritten almost entirely from stolen MIT original by Jim Gettys,
14   The Institute for Advanced Study, Princeton, NJ. */
15
16/* this program written to read Ansi labeled tapes produced by Vax/VMS 2.5*/
17/* results on other tapes/or versions of VMS 3.0 or later not guaranteed.*/
18
19/* note that the variable record file may not be what you want for fortran */
20/* written unformatted files, which add a 2 byte segment code at the start*/
21/* of each record.  The accompanying program "unseg" will create Unix fortran*/
22/* style files from a VMS fortran segmented file. Note that VMS creates these*/
23/* segmented files by default.*/
24
25#define BINARY 0                /*binary files are copied in unchanged*/
26                                /* .exe or Eunice stream files*/
27#define CRLF 1                  /*insert new line after each record*/
28                                /* typical .for, .lis etc text files*/
29#define FORTRAN 2               /*fortran carriage control interpretation*/
30                                /* output of fortran programs*/
31#define VARIABLE 3              /*read in variable length recs, transcribe */
32                                /* to unix fortran style variable records*/
33                                /* sequential fortran (unformatted) or .obj */
34                                /* files, transcribed to Unix fortran files*/
35
36int vnos = 1;                   /*restore version numbers of files*/
37int verbose = 0;
38int superverbose = 0;           /*super verbose mode*/
39int fbinary = 0;                /*force binary input mode, debugging*/
40int list = 0;                   /*listing mode*/
41
42/* the following structure definitions generated in reference to DEC VAX/VMS
43        magnetic tape user's guide, appendix a */
44
45int fbsize;                     /*file block size determined from tape*/
46char cbuffer[100];              /*numeric conversion buffer*/
47
48struct volume1 {
49        char v_lid[3];          /*label id*/
50        char v_num;             /*label number*/
51        char v_id[6];           /*volume id*/
52        char v_acc;             /*volume access*/
53        char v_res1[26];        /*reserved space*/
54        char v_owner[13];       /*owner identifier*/
55        char v_std;             /*Digital Standard*/
56        char v_res2[28];        /*reseved space*/
57        char v_lstd;            /*label Standard Version 1 (3)*/
58        } vol1;
59
60struct header1 {                /*hdr1 record format*/
61        char h1_lid[3];         /*label id*/
62        char h1_num;            /*label number (1)*/
63        char h1_fname[17];      /*file identifier*/
64        char h1_fset[6];        /*file set id*/
65        char h1_fsec[4];        /*file section number*/
66        char h1_seqno[4];       /*file sequence number*/
67        char h1_genno[4];       /*generation number*/
68        char h1_gverno[2];      /*version of generation number*/
69        char h1_credate[6];     /*creation date*/
70        char h1_exdate[6];      /*expiration date*/
71        char h1_access;         /*file accessability*/
72        char h1_blcount[6];     /*block count (always zero from DEC on hdr1*/
73        char h1_syscode[13];    /*system code, should be DECFILE11A*/
74        char h1_res1[7];        /*reserved space*/
75        } hdr1;
76struct header2 {                /*hdr2 record format*/
77        char h2_lid[3];         /*label id*/
78        char h2_num;            /*label number(should be a 2)*/
79        char h2_format;         /*record format F is fixed, D is Variable*/
80        char h2_bsize[5];       /*maximum number of chars/block*/
81        char h2_rlength[5];     /*record length fixed, max length variable*/
82        char h2_flag;           /*flag for RMS cruft*/
83        char h2_rmscrud1[20];   /*for VMS 2.0 and earlier, contains RMS Crud*/
84        char h2_form;           /*forms control, A means fortran,
85                                  M imbedded control, space means crlf needed*/
86        char h2_morerms[13];    /*more rms stuff*/
87        char h2_buffoff[2];     /*buffer offset, should be 00*/
88        char h2_res1[28];       /*reserved for future use*/
89        } hdr2;
90
91char buffer[32768];     /* buffer for raw reads from magtape */
92char nl[] = "\n";       /* carriage control characters */
93char ff[] = "\f";
94char cr[] = "\r";
95
96main(argc,argv)
97int argc;
98char *argv[];
99 {      register int i;
100        register char *p;
101        int version,genno,genver;
102        char filename[25];              /* recreated file name */
103        int bf,ef = argc;               /* beginning and ending files*/
104        char *s;
105        char *tfile = "/dev/rmt8";      /* pointer to tape to open */
106        int match = 0;                  /* file name match with argument list*/
107        int first;
108        int tape,file,bitbucket,c,ftype;
109        for(i = 0; i < argc; i++) {
110                if(argv[i][0] != '-') continue;
111                bf = i + 1;             /* save last argument found*/
112                for(s = argv[i] + 1; *s != '\0'; s++)
113                        switch(*s) {
114                                case 0:
115                                        break;
116                                case 'b':
117                                        fbinary = 1;
118                                        printf("ansi: warning, binary input forced.\n");
119                                        break;
120                                case 'v':
121                                        verbose = 1;
122                                        break;
123                                case 's':
124                                        superverbose = 1;
125                                        verbose = 1;
126                                        break;
127                                case 'f':
128                                        bf += 1;        /*skip drive*/
129                                        tfile = argv[i + 1];
130                                        printf("file %s\n",argv[1]);
131                                        break;
132                                case 'i':
133                                        vnos = 0;
134                                        break;
135                                case 'l':
136                                        list = 1;
137                                        verbose = 1;
138                                        break;
139                                default:
140                                        fprintf(stderr,
141                                                "usage: ansi -[bfilsv tape files]\n");
142                                        exit(1);
143                        }
144                }
145
146        bitbucket = open("/dev/null",1);
147        tape = open(tfile,0);           /* acquire the tape drive */
148        if (tape == -1) {
149                printf("Can't open %s\n",tfile);
150                exit(-1);
151                }
152
153        if ((c=read(tape,&vol1,80)) != 80) {    /* read in volume label */
154                printf("Error in reading volume label.\n");
155                exit(-1);
156                }
157        if(verbose) printf("Volume label found was %6.6s.\n",vol1.v_id);
158
159        while (1) {                     /* loop to read files from tape */
160
161        /* read in hdr1 label, error => all done */
162        if (read(tape,&hdr1,80) != 80) {
163                exit(0);
164                }
165
166        if (superverbose) dump1(&hdr1);
167
168        for (i=0,p=hdr1.h1_fname; i++<17 && *p!=' '; p++)
169        if (*p>='A' && *p<='Z') *p |= 040;      /* look for end */
170        *p = '\0';                              /* terminate name with null */
171
172        /* reextract version number from tape*/
173        convert(4,hdr1.h1_genno,&genno);
174        convert(2,hdr1.h1_gverno,&genver);
175        version = (genno-1)*100 + genver + 1;
176
177        if (vnos) sprintf(filename,"%s.%d",hdr1.h1_fname,version);
178        else strcpy(filename,hdr1.h1_fname);
179
180        /* see if file on list of files to be extracted */
181        match = 0;
182        for(i = bf; i < ef; i++)
183                if(strcmp(argv[i],filename) == 0) {
184                                match = 1;
185                                break;
186                                }
187
188        if(bf >= ef) match = 1;
189        if(list) match = 0;                     /* don't retrieve files if
190                                                   listing volume contents*/
191        first = 0;
192        file = bitbucket;
193        if(match) {
194                if(verbose) printf("Creating file %s, ",filename) ;
195                fflush(stdout);                 /* let him see it */
196                file = creat(filename,0666);    /* and use remainder as name */
197                first = 1;
198                if (file==-1) {
199                        printf("Can't create %s, skipping file on tape.\n"
200                                ,filename);
201                        file = bitbucket;
202                        }
203                }
204        if(list) { first = 1; printf("%s, ",filename) ; }
205
206        if (read(tape,&hdr2,80) != 80) {
207                printf("Bad HDR2 record!\n");
208                exit(1);
209                }
210
211        if (superverbose) dump2(&hdr2);
212        convert(5,&hdr2.h2_bsize[0],&fbsize);
213
214
215        ftype = BINARY;         /*default to binary input*/
216        /* lets decode the record format and forms control properly*/   
217        switch(hdr2.h2_format) {
218            case 'D':
219                switch(hdr2.h2_form) {
220                case 'A':       ftype = FORTRAN;
221                                break;
222                case 'M':       ftype = VARIABLE;
223                                break;
224                case ' ':       ftype = CRLF;
225                                break;
226                default:        fprintf(stderr,
227                                "ansi: bad forms, binary assumed in %s.\n"
228                                        ,filename);
229                                ftype = BINARY;
230                                break;
231                                }
232                break;
233            case 'F':
234                ftype = BINARY;
235                if(hdr2.h2_form != 'M')
236                         fprintf(stderr,
237                                "ansi: unknown type, binary assumed in %s.\n",
238                                         filename);
239                break;
240            default:
241                ftype = BINARY;
242                fprintf(stderr,"ansi: unknown format, binary assumed in %s.\n",
243                                filename);
244                }
245        if(fbinary) ftype = BINARY;
246
247        if(first) {
248                char *out;              /*text string to output*/
249                printf("file type is ") ;
250                switch(ftype) {
251                        case BINARY:    out = "fixed binary or stream.";break;
252                        case CRLF:      out = "text.";                  break;
253                        case FORTRAN:   out = "fortran text.";          break;
254                        case VARIABLE:  out = "variable binary.";       break;
255                        default:        out = "unknown.";               break;
256                        }
257                printf("%s\n",out);
258                }
259
260        /* skip rest of header file, last read skips eof */
261        while ((c = read(tape,buffer,80)) == 80);
262       
263        /* binary files get read as is... */
264        if (ftype == BINARY) while (1) {
265                c = read(tape,buffer,fbsize);
266                if (c == 0) break;
267                write(file,buffer,c);
268                }
269        else while (1) {                /* read in records of file */
270                c = read(tape,buffer,fbsize);/*read in next record from tape */
271                if (c == 0) break;      /* EOF => all done with this file */
272                if (c != fbsize) printf("Record wrong size (count = %d)\n",c);
273                p = buffer;
274
275                /* ^ as count means end of buffer */
276                while (p < &buffer[fbsize] && *p != '^') {
277                        int length;
278                        for (i=0,c=0; i<4; i++) c = c*10 + *p++ - '0';
279                        c -= 4;
280                        length = c;
281                        switch(ftype) {
282                                case FORTRAN:
283                                        switch(*p) {    /* do fortran crock */
284                                            default:
285                                            case ' ':
286                                                write(file,nl,1); /* NL */
287                                                break;
288                                            case '0':
289                                                write(file,nl,1); /* NL */
290                                                write(file,nl,1); /* NL */
291                                                break;
292                                            case '+':
293                                                write(file,cr,1); /* CR */
294                                                break;
295                                            case '1':
296                                                write(file,ff,1); /* FF */
297                                                break;
298                                                }
299                                        write(file,p+1,c-1);
300                                        break;
301                                case VARIABLE:
302                                        write(file,&length,sizeof(length));
303                                        write(file,p,c);
304                                        write(file,&length,sizeof(length));
305                                        break;
306                                case CRLF:
307                                        write(file,p,c);
308                                        write(file,nl,1); /*add newline*/
309                                        break;
310                                }
311                        p += c;
312                        }
313                }       /* end of record reading loop */
314                /* terminate last fortran record */
315        if(ftype == FORTRAN) write(file,nl,1);
316
317        if (file != bitbucket) close(file);
318
319        /* skip EOF file, last read skips eof */
320        while ((c = read(tape,buffer,80)) == 80);
321        }                                       /* end of loop to read files */
322}
323
324dump1(h)
325        struct header1 *h;
326        {
327        printf("label id %3.3s\n",h->h1_lid);
328        printf("label number %c\n",h->h1_num);
329        printf("name %17.17s\n",h->h1_fname);
330        printf("set id %6.6s\n",h->h1_fset);
331        printf("section number %4.4s\n",h->h1_fsec);
332        printf("sequence number %4.4s\n",h->h1_seqno);
333        printf("generation number %4.4s\n",h->h1_genno);
334        printf("generation version number %2.2s\n",h->h1_gverno);
335        printf("creation date %6.6s\n",h->h1_credate);
336        printf("expiration date %6.6s\n",h->h1_exdate);
337        printf("access code %c\n",h->h1_access);
338        printf("block count %6.6s\n",h->h1_blcount);
339        printf("system code %13.13s\n",h->h1_syscode);
340        return;
341        }
342dump2(h)
343        struct header2 *h;
344        {
345        printf("label id %3.3s\n",h->h2_lid);
346        printf("label number %c\n",h->h2_num);
347        printf("format %c\n",h->h2_format);
348        printf("block size %5.5s\n",h->h2_bsize);
349        printf("record length %5.5s\n",h->h2_rlength);
350        printf("rms flag %c\n",h->h2_flag);
351        printf("forms control %c\n",h->h2_form);
352        printf("buffer offset %2.2s\n",h->h2_buffoff);
353        return;
354        }
355
356convert(howmany,where,value)
357int howmany;                    /*number of characters in numeric field*/
358char *where;                    /*where to get the characters*/
359int *value;                     /*place to put the result*/
360        {
361        int i;
362        char *cptr = &cbuffer[0];       /*pointer to temp area*/
363        while(howmany--) *cptr++ = *where++;
364        *cptr++ = '\0';         /*terminate the string*/
365        *value = atoi(cbuffer); /*get and store the value*/
366        }
Note: See TracBrowser for help on using the repository browser.