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