]> arthur.barton.de Git - netatalk.git/blob - bin/megatron/megatron.c
Warning fixes.
[netatalk.git] / bin / megatron / megatron.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <sys/types.h>
6 #include <sys/param.h>
7 #include <sys/stat.h>
8 #include <sys/uio.h>
9 #include <fcntl.h>
10 #include <time.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <syslog.h>
15 #include <netatalk/endian.h>
16 #include "asingle.h"
17 #include "megatron.h"
18 #include "hqx.h"
19 #include "macbin.h"
20 #include "nad.h"
21
22 char            forkbuf[8192];
23 char            *forkname[] = { "data", "resource" };
24 char            *name[] = { "unhex",
25                             "unbin",
26                             "unsingle",
27                             "macbinary",
28                             "hqx2bin",
29                             "single2bin",
30                             "nadheader",
31                             "binheader",
32                             "megatron" };
33
34 int from_open( un, file, fh, flags )
35     int                 un, flags;
36     char                *file;
37     struct FHeader      *fh;
38 {
39     switch ( un ) {
40         case MEGATRON :
41         case HEX2NAD :
42         case HEX2BIN :
43             return( hqx_open( file, O_RDONLY, fh, flags ));
44             break;
45         case BIN2NAD :
46         case BINHEADER:
47             return( bin_open( file, O_RDONLY, fh, flags ));
48             break;
49         case NAD2BIN :
50         case NADHEADER:
51             return( nad_open( file, O_RDONLY, fh, flags ));
52             break;
53         case SINGLE2NAD :
54         case SINGLE2BIN :
55             return( single_open( file, O_RDONLY, fh, flags ));
56         default :
57             return( -1 );
58             break;
59     }
60 }
61
62 int from_read( un, fork, buf, len )
63     int                 un;
64     int                 fork;
65     char                *buf;
66     int                 len;
67 {
68     switch ( un ) {
69         case MEGATRON :
70         case HEX2NAD :
71         case HEX2BIN :
72             return( hqx_read( fork, buf, len ));
73             break;
74         case BIN2NAD :
75             return( bin_read( fork, buf, len ));
76             break;
77         case NAD2BIN :
78             return( nad_read( fork, buf, len ));
79             break;
80         case SINGLE2NAD :
81         case SINGLE2BIN :
82             return( single_read( fork, buf, len ));
83         default :
84             return( -1 );
85             break;
86     }
87 }
88
89 int from_close( un )
90     int                 un;
91 {
92     switch ( un ) {
93         case MEGATRON :
94         case HEX2NAD :
95         case HEX2BIN :
96             return( hqx_close( KEEP ));
97             break;
98         case BIN2NAD :
99             return( bin_close( KEEP ));
100             break;
101         case NAD2BIN :
102             return( nad_close( KEEP ));
103             break;
104         case SINGLE2NAD :
105         case SINGLE2BIN :
106             return( single_close( KEEP ));
107         default :
108             return( -1 );
109             break;
110     }
111 }
112
113 int to_open( to, file, fh, flags )
114     int                 to, flags;
115     char                *file;
116     struct FHeader      *fh;
117 {
118     switch ( to ) {
119         case MEGATRON :
120         case HEX2NAD :
121         case BIN2NAD :
122         case SINGLE2NAD :
123             return( nad_open( file, O_RDWR|O_CREAT|O_EXCL, fh, flags ));
124             break;
125         case NAD2BIN :
126         case HEX2BIN :
127         case SINGLE2BIN :
128             return( bin_open( file, O_RDWR|O_CREAT|O_EXCL, fh, flags ));
129             break;
130         default :
131             return( -1 );
132             break;
133     }
134 }
135
136 int to_write( to, fork, bufc )
137     int                 to;
138     int                 fork;
139     int                 bufc;
140 {
141     switch ( to ) {
142         case MEGATRON :
143         case HEX2NAD :
144         case BIN2NAD :
145         case SINGLE2NAD :
146             return( nad_write( fork, forkbuf, bufc ));
147             break;
148         case NAD2BIN :
149         case HEX2BIN :
150         case SINGLE2BIN :
151             return( bin_write( fork, forkbuf, bufc ));
152             break;
153         default :
154             return( -1 );
155             break;
156     }
157 }
158
159 int to_close( to, keepflag )
160     int                 to;
161     int                 keepflag;
162 {
163     switch ( to ) {
164         case MEGATRON :
165         case HEX2NAD :
166         case BIN2NAD :
167         case SINGLE2NAD :
168             return( nad_close( keepflag ));
169             break;
170         case NAD2BIN :
171         case HEX2BIN :
172         case SINGLE2BIN :
173             return( bin_close( keepflag ));
174             break;
175         default :
176             return( -1 );
177             break;
178     }
179 }
180
181 int megatron( path, module, newname, flags )
182     char        *path, *newname;
183     int         module, flags;
184 {
185     struct stat         st;
186     struct FHeader      fh;
187     int                 bufc;
188     int                 fork;
189     int                 forkred;
190
191 /*
192  * If the source file is not stdin, make sure it exists and
193  * that it is not a directory.
194  */
195
196     if ( strcmp( path, STDIN ) != 0 ) {
197         if ( stat( path, &st ) < 0 ) {
198             perror( path );
199             return( -1 );
200         }
201         if ( S_ISDIR( st.st_mode )) {
202             fprintf( stderr, "%s is a directory.\n", path );
203             return( 0 );
204         }
205     }
206
207 /*
208  * Open the source file and fill in the file header structure.
209  */
210
211     memset( &fh, 0, sizeof( fh ));
212     if ( from_open( module, path, &fh ) < 0 ) {
213         return( -1 );
214     }
215
216     if ( flags & OPTION_HEADERONLY ) {
217         time_t t;
218         char buf[5] = "";
219         int i;
220
221         printf("name:               %s\n",fh.name);
222         printf("comment:            %s\n",fh.comment);
223         memcpy(&buf, &fh.finder_info.fdCreator, sizeof(u_int32_t));
224         printf("creator:            '%4s'\n", buf);
225         memcpy(&buf, &fh.finder_info.fdType, sizeof(u_int32_t));
226         printf("type:               '%4s'\n", buf);
227         for(i=0; i < NUMFORKS; ++i) 
228           printf("fork length[%d]:     %u\n", i, ntohl(fh.forklen[i]));
229         t = AD_DATE_TO_UNIX(fh.create_date);
230         printf("creation date:      %s", ctime(&t));
231         t = AD_DATE_TO_UNIX(fh.mod_date);
232         printf("modification date:  %s", ctime(&t));
233         t = AD_DATE_TO_UNIX(fh.backup_date);
234         printf("backup date:        %s", ctime(&t));
235         return( from_close( module ));
236     }
237     
238 /*
239  * Open the target file and write out the file header info.
240  * set the header to the new filename if it has been supplied.
241  */
242
243     if (*newname)
244         strcpy(fh.name, newname);
245
246     if ( to_open( module, path, &fh, flags ) < 0 ) {
247         (void)from_close( module );
248         return( -1 );
249     }
250
251 /*
252  * Read in and write out the data and resource forks.
253  */
254
255     for ( fork = 0; fork < NUMFORKS ; fork++ ) {
256         forkred = 0;
257         while(( bufc = from_read( module, fork, forkbuf, sizeof( forkbuf )))
258                 > 0 ) {
259             if ( to_write( module, fork, bufc ) != bufc ) {
260                 fprintf( stderr, "%s: Probable write error\n", path );
261                 to_close( module, TRASH );
262                 (void)from_close( module );
263                 return( -1 );
264             }
265             forkred += bufc;
266         }
267 #if DEBUG
268         fprintf( stderr, "megatron: forkred is \t\t%d\n", forkred );
269         fprintf( stderr, "megatron: fh.forklen[%d] is \t%d\n", fork, 
270                 ntohl( fh.forklen[ fork ] ));
271 #endif
272         if (( bufc < 0 ) || ( forkred != ntohl( fh.forklen[ fork ] ))) {
273             fprintf( stderr, "%s: Problem with input, dude\n", path );
274             to_close( module, TRASH );
275             (void)from_close( module );
276             return( -1 );
277         }
278     }
279
280 /*
281  * Close up the files, and get out of here.
282  */
283
284     if ( to_close( module, KEEP ) < 0 ) {
285         perror( "megatron:" );
286         (void)to_close( module, TRASH );
287     }
288     return( from_close( module ));
289 }
290
291 int main( argc, argv )
292     int         argc;
293     char        **argv;
294 {
295     int         rc, c;
296     int         rv = 0;
297     int         converts = sizeof(name) / sizeof(char *);
298     int         module = -1;
299     int         flags = 0;
300     char        *progname, newname[ADEDLEN_NAME + 1];
301
302     progname = strrchr( argv[ 0 ], '/' );
303     if (( progname == NULL ) || ( progname == '\0' )) {
304         progname = argv[ 0 ];
305     } else progname++;
306
307 #if DEBUG
308     if ( CONVERTS != converts ) {
309         fprintf( stderr, "megatron: list of program links messed up\n" );
310         return( -1 );
311     }
312 #endif
313
314     for ( c = 0 ; (( c < converts ) && ( module < 0 )) ; ++c ) {
315         if ( strcmp( name[ c ], progname ) == 0 ) module = c;
316     }
317     if ( module == -1 ) module = ( converts - 1 );
318     if ((module == NADHEADER) || (module == BINHEADER))
319       flags |= OPTION_HEADERONLY;
320
321     if ( argc == 1 ) {
322         return( megatron( STDIN, module, newname, flags ));
323     }
324
325     *newname = '\0';
326     for ( c = 1 ; c < argc ; ++c ) {
327         if ( strcmp( argv [ c ], "--header" ) == 0 ) {
328             flags |= OPTION_HEADERONLY;
329             continue;
330         }
331         if ( strcmp( argv [ c ], "--filename" ) == 0 ) {
332           if(++c < argc) strncpy(newname,argv[c], ADEDLEN_NAME);
333           continue;
334         }
335         if (strcmp(argv[c], "--stdout") == 0) {
336           flags |= OPTION_STDOUT;
337           continue;
338         }
339           
340         rc = megatron( argv[ c ], module, newname, flags);
341         if ( rc != 0 ) {
342             rv = rc;
343         }
344         *newname = '\0';
345     }
346     return( rv );
347 }
348