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