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