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