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