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