~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to bin/megatron/nad.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: nad.c,v 1.11 2002/04/29 01:52:50 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/time.h>
 
13
#include <sys/uio.h>
 
14
#include <ctype.h>
 
15
#include <errno.h>
 
16
#include <stdio.h>
 
17
#include <string.h>
 
18
#include <dirent.h>
 
19
#ifdef HAVE_FCNTL_H
 
20
#include <fcntl.h>
 
21
#endif /* HAVE_FCNTL_H */
 
22
 
 
23
#include <atalk/adouble.h>
 
24
#include <netatalk/endian.h>
 
25
#include "megatron.h"
 
26
#include "nad.h"
 
27
 
 
28
static char             hexdig[] = "0123456789abcdef";
 
29
 
 
30
static char mtou_buf[MAXPATHLEN + 1], utom_buf[MAXPATHLEN + 1];
 
31
static char *mtoupathcap( mpath )
 
32
    char        *mpath;
 
33
{
 
34
    char        *m, *u, *umax;
 
35
    int         i = 0;
 
36
 
 
37
    m = mpath;
 
38
    u = mtou_buf;
 
39
    umax = u + sizeof(mtou_buf) - 4;
 
40
    while ( *m != '\0' && u < umax) {
 
41
#if AD_VERSION == AD_VERSION1
 
42
        if ( !isascii( *m ) || *m == '/' || ( i == 0 && *m == '.' )) {
 
43
#else /* AD_VERSION == AD_VERSION1 */
 
44
        if (!isprint(*m) || *m == '/' || ( i == 0 && (*m == '.' ))) {
 
45
#endif /* AD_VERSION == AD_VERSION1 */
 
46
            *u++ = ':';
 
47
            *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
 
48
            *u++ = hexdig[ *m & 0x0f ];
 
49
        } else {
 
50
#ifdef DOWNCASE
 
51
            *u++ = ( isupper( *m )) ? tolower( *m ) : *m;
 
52
#else /* DOWNCASE */
 
53
            *u++ = *m;
 
54
#endif /* DOWNCASE */
 
55
        }
 
56
        i++;
 
57
        m++;
 
58
    }
 
59
    *u = '\0';
 
60
    return( mtou_buf );
 
61
}
 
62
 
 
63
 
 
64
#define hextoint( c )   ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
 
65
#define islxdigit(x)    (!isupper(x)&&isxdigit(x))
 
66
 
 
67
static char *utompathcap( upath )
 
68
    char        *upath;
 
69
{
 
70
    char        *m, *u;
 
71
    int h;
 
72
 
 
73
    m = utom_buf;
 
74
    u = upath;
 
75
    while ( *u != '\0' ) {
 
76
        if (*u == ':' && *(u + 1) != '\0' && islxdigit(*(u+1)) &&
 
77
            *(u+2) != '\0' && islxdigit(*(u+2))) {
 
78
          u++;
 
79
          h = hextoint(*u) << 4;
 
80
          u++;
 
81
          h |= hextoint(*u);
 
82
          *m = h;
 
83
        } else {
 
84
#ifdef DOWNCASE
 
85
          *m = diatolower(*u);
 
86
#else /* DOWNCASE */
 
87
          *m = *u;
 
88
#endif /* DOWNCASE */
 
89
        }
 
90
        u++;
 
91
        m++;
 
92
    }
 
93
    *m = '\0';
 
94
    return( utom_buf );
 
95
}
 
96
 
 
97
static void euc2sjis( int *p1, int *p2) /* agrees w/ Samba on valid codes */
 
98
{
 
99
    int row_offset, cell_offset;
 
100
    unsigned char c1, c2;
 
101
 
 
102
    /* first convert EUC to ISO-2022 */
 
103
    c1 = *p1 & 0x7F;
 
104
    c2 = *p2 & 0x7F;
 
105
 
 
106
    /* now convert ISO-2022 to Shift-JIS */
 
107
    row_offset = c1 < 95 ? 112 : 176;
 
108
    cell_offset = c1 % 2 ? (c2 > 95 ? 32 : 31) : 126;
 
109
 
 
110
    *p1 = ((c1 + 1) >> 1) + row_offset;
 
111
    *p2 = c2 + cell_offset;
 
112
}
 
113
 
 
114
static void sjis2euc( int *p1, int *p2)  /* agrees w/ Samba on valid codes */
 
115
{
 
116
    int row_offset, cell_offset, adjust;
 
117
    unsigned char c1, c2;
 
118
 
 
119
    c1 = *p1;
 
120
    c2 = *p2;
 
121
 
 
122
    /* first convert Shift-JIS to ISO-2022 */
 
123
    adjust = c2 < 159;
 
124
    row_offset = c1 < 160 ? 112 : 176;
 
125
    cell_offset = adjust ? (c2 > 127 ? 32 : 31) : 126;
 
126
 
 
127
    c1 = ((c1 - row_offset) << 1) - adjust;
 
128
    c2 -= cell_offset;
 
129
 
 
130
    /* now convert ISO-2022 to EUC */
 
131
    *p1 = c1 | 0x80;
 
132
    *p2 = c2 | 0x80;
 
133
}
 
134
 
 
135
static char *mtoupatheuc( char *from)
 
136
{
 
137
    unsigned char *in, *out, *maxout;
 
138
    int p, p2, i = 0;
 
139
 
 
140
    in = (unsigned char *) from;
 
141
    out = (unsigned char *) mtou_buf;
 
142
 
 
143
    if( *in ) {
 
144
        maxout = out + sizeof( mtou_buf) - 3;
 
145
 
 
146
        while( out < maxout ) {
 
147
            p = *in++;
 
148
 
 
149
            if( ((0x81 <= p) && (p <= 0x9F))
 
150
             || ((0xE0 <= p) && (p <= 0xEF)) ) {
 
151
                /* JIS X 0208 */
 
152
                p2 = *in++;
 
153
                if( ((0x40 <= p2) && (p2 <= 0x7E))
 
154
                 || ((0x80 <= p2) && (p2 <= 0xFC)) )
 
155
                    sjis2euc( &p, &p2);
 
156
                *out++ = p;
 
157
                p = p2;
 
158
 
 
159
            } else if( (0xA1 <= p) && (p <= 0xDF) ) {
 
160
                *out++ = 0x8E;  /* halfwidth katakana */
 
161
            } else if( p < 0x80 ) {
 
162
#ifdef DOWNCASE
 
163
                p = ( isupper( p )) ? tolower( p ) : p;
 
164
#endif /* DOWNCASE */
 
165
            }
 
166
            if( ( p == '/') || ( i == 0 && p == '.' ) ) {
 
167
                *out++ = ':';
 
168
                *out++ = hexdig[ ( p & 0xf0 ) >> 4 ];
 
169
                p = hexdig[ p & 0x0f ];
 
170
            }
 
171
            i++;
 
172
            *out++ = p;
 
173
            if( p )
 
174
                continue;
 
175
            break;
 
176
        }
 
177
    } else {
 
178
        *out++ = '.';
 
179
        *out = 0;
 
180
    }
 
181
 
 
182
    return mtou_buf;
 
183
}
 
184
 
 
185
static char *utompatheuc( char *from)
 
186
{
 
187
    unsigned char *in, *out, *maxout;
 
188
    int p, p2;
 
189
 
 
190
    in = (unsigned char *) from;
 
191
    out = (unsigned char *) utom_buf;
 
192
    maxout = out + sizeof( utom_buf) - 3;
 
193
 
 
194
    while( out < maxout ) {
 
195
        p = *in++;
 
196
 
 
197
        if( (0xA1 <= p) && (p <= 0xFE) ) {      /* JIS X 0208 */
 
198
            p2 = *in++;
 
199
            if( (0xA1 <= p2) && (p2 <= 0xFE) )
 
200
                euc2sjis( &p, &p2);
 
201
            *out++ = p;
 
202
            p = p2;
 
203
        } else if( p == 0x8E ) {                /* halfwidth katakana */
 
204
            p = *in++;
 
205
        } else if( p < 0x80 ) {
 
206
#ifdef DOWNCASE
 
207
            p = ( isupper( p )) ? tolower( p ) : p;
 
208
#endif /* DOWNCASE */
 
209
        }
 
210
        if ( p == ':' && *(in) != '\0' && islxdigit( *(in)) &&
 
211
                *(in+1) != '\0' && islxdigit( *(in+1))) {
 
212
           p = hextoint( *in ) << 4;
 
213
           in++;
 
214
           p |= hextoint( *in );
 
215
           in++;
 
216
        }
 
217
        *out++ = p;
 
218
        if( p )
 
219
            continue;
 
220
        break;
 
221
    }
 
222
 
 
223
    return utom_buf;
 
224
}
 
225
 
 
226
static char *mtoupathsjis( char *from)
 
227
{
 
228
    unsigned char *in, *out, *maxout;
 
229
    int p, p2, i = 0;
 
230
 
 
231
    in = (unsigned char *) from;
 
232
    out = (unsigned char *) mtou_buf;
 
233
 
 
234
    if( *in ) {
 
235
        maxout = out + sizeof( mtou_buf) - 3;
 
236
 
 
237
        while( out < maxout ) {
 
238
            p = *in++;
 
239
 
 
240
            if( ((0x81 <= p) && (p <= 0x9F))
 
241
             || ((0xE0 <= p) && (p <= 0xEF)) ) {
 
242
                /* JIS X 0208 */
 
243
                p2 = *in++;
 
244
                *out++ = p;
 
245
                p = p2;
 
246
 
 
247
            } else if( (0xA1 <= p) && (p <= 0xDF) ) {
 
248
                ;       /* halfwidth katakana */
 
249
            } else if(p < 0x80 ) {
 
250
#ifdef DOWNCASE
 
251
                p = ( isupper( p )) ? tolower( p ) : p;
 
252
#endif /* DOWNCASE */
 
253
            }
 
254
            if( ( p == '/') || ( i == 0 && p == '.' ) ) {
 
255
                *out++ = ':';
 
256
                *out++ = hexdig[ ( p & 0xf0 ) >> 4 ];
 
257
                p = hexdig[ p & 0x0f ];
 
258
            }
 
259
            i++;
 
260
            *out++ = p;
 
261
            if( p )
 
262
                continue;
 
263
            break;
 
264
        }
 
265
    } else {
 
266
        *out++ = '.';
 
267
        *out = 0;
 
268
    }
 
269
 
 
270
    return mtou_buf;
 
271
}
 
272
 
 
273
static char *utompathsjis( char *from)
 
274
{
 
275
    unsigned char *in, *out, *maxout;
 
276
    int p, p2;
 
277
 
 
278
    in = (unsigned char *) from;
 
279
    out = (unsigned char *) utom_buf;
 
280
    maxout = out + sizeof( utom_buf) - 3;
 
281
 
 
282
    while( out < maxout ) {
 
283
        p = *in++;
 
284
 
 
285
        if( (0xA1 <= p) && (p <= 0xFE) ) {      /* JIS X 0208 */
 
286
            p2 = *in++;
 
287
            *out++ = p;
 
288
            p = p2;
 
289
        } else if( p == 0x8E ) {                /* do nothing */
 
290
            ;
 
291
        } else if( p < 0x80 ) {
 
292
#ifdef DOWNCASE
 
293
           p = ( isupper( p )) ? tolower( p ) : p;
 
294
#endif /* DOWNCASE */
 
295
        }
 
296
        if ( p == ':' && *(in) != '\0' && islxdigit( *(in)) &&
 
297
                *(in+1) != '\0' && islxdigit( *(in+1))) {
 
298
           p = hextoint( *in ) << 4;
 
299
           in++;
 
300
           p |= hextoint( *in );
 
301
           in++;
 
302
        }
 
303
        *out++ = p;
 
304
        if( p )
 
305
            continue;
 
306
        break;
 
307
    }
 
308
 
 
309
    return utom_buf;
 
310
 }
 
311
 
 
312
char * (*_mtoupath) ( char *mpath) = mtoupathcap;
 
313
char * (*_utompath) ( char *upath) = utompathcap;
 
314
 
 
315
/* choose translators for optional character set */
 
316
void select_charset( int options)
 
317
{
 
318
 
 
319
    if( options & OPTION_EUCJP ) {
 
320
        _mtoupath = mtoupatheuc;
 
321
        _utompath = utompatheuc;
 
322
    } else if( options & OPTION_SJIS ) {
 
323
        _mtoupath = mtoupathsjis;
 
324
        _utompath = utompathsjis;
 
325
    } else {
 
326
        _mtoupath = mtoupathcap;
 
327
        _utompath = utompathcap;
 
328
    }
 
329
}
 
330
 
 
331
 
 
332
#if HEXOUTPUT
 
333
    int                 hexfork[ NUMFORKS ];
 
334
#endif /* HEXOUTPUT */
 
335
 
 
336
struct nad_file_data {
 
337
    char                macname[ MAXPATHLEN + 1 ];
 
338
    char                adpath[ 2 ][ MAXPATHLEN + 1];
 
339
    int                 offset[ NUMFORKS ];
 
340
    struct adouble      ad;
 
341
} nad;
 
342
 
 
343
int nad_open( path, openflags, fh, options )
 
344
    char                *path;
 
345
    int                 openflags, options;
 
346
    struct FHeader      *fh;
 
347
{
 
348
    struct stat         st;
 
349
    int                 fork;
 
350
 
 
351
/*
 
352
 * Depending upon openflags, set up nad.adpath for the open.  If it 
 
353
 * is for write, then stat the current directory to get its mode.
 
354
 * Open the file.  Either fill or grab the adouble information.
 
355
 */
 
356
    select_charset( options);
 
357
    memset(&nad.ad, 0, sizeof(nad.ad));
 
358
    if ( openflags == O_RDONLY ) {
 
359
        strcpy( nad.adpath[0], path );
 
360
        strcpy( nad.adpath[1], 
 
361
                ad_path( nad.adpath[0], ADFLAGS_DF|ADFLAGS_HF ));
 
362
        for ( fork = 0 ; fork < NUMFORKS ; fork++ ) {
 
363
            if ( stat( nad.adpath[ fork ], &st ) < 0 ) {
 
364
                if ( errno == ENOENT ) {
 
365
                    fprintf( stderr, "%s is not an adouble file.\n", path );
 
366
                } else {
 
367
                    perror( "stat of adouble file failed" );
 
368
                }
 
369
                return( -1 );
 
370
            }
 
371
        }
 
372
 
 
373
#if DEBUG
 
374
    fprintf(stderr, "%s is adpath[0]\n", nad.adpath[0]);
 
375
    fprintf(stderr, "%s is adpath[1]\n", nad.adpath[1]);
 
376
#endif /* DEBUG */
 
377
        if ( ad_open( nad.adpath[ 0 ], ADFLAGS_DF|ADFLAGS_HF,
 
378
                openflags, (int)( st.st_mode & 0666 ), &nad.ad) < 0 ) {
 
379
            perror( nad.adpath[ 0 ] );
 
380
            return( -1 );
 
381
        }
 
382
        return( nad_header_read( fh ));
 
383
 
 
384
    } else {
 
385
        strcpy( nad.macname, fh->name );
 
386
        strcpy( nad.adpath[0], mtoupath( nad.macname ));
 
387
        strcpy( nad.adpath[1], 
 
388
                ad_path( nad.adpath[0], ADFLAGS_DF|ADFLAGS_HF ));
 
389
#if DEBUG
 
390
    fprintf(stderr, "%s\n", nad.macname);
 
391
    fprintf(stderr, "%s is adpath[0]\n", nad.adpath[0]);
 
392
    fprintf(stderr, "%s is adpath[1]\n", nad.adpath[1]);
 
393
#endif /* DEBUG */
 
394
        if ( stat( ".", &st ) < 0 ) {
 
395
            perror( "stat of . failed" );
 
396
            return( -1 );
 
397
        }
 
398
        (void)umask( 0 );
 
399
        if ( ad_open( nad.adpath[ 0 ], ADFLAGS_DF|ADFLAGS_HF,
 
400
                openflags, (int)( st.st_mode & 0666 ), &nad.ad) < 0 ) {
 
401
            perror( nad.adpath[ 0 ] );
 
402
            return( -1 );
 
403
        }
 
404
        return( nad_header_write( fh ));
 
405
    }
 
406
}
 
407
 
 
408
int nad_header_read( fh )
 
409
    struct FHeader      *fh;
 
410
{
 
411
    u_int32_t           temptime;
 
412
    struct stat         st;
 
413
 
 
414
    memcpy( nad.macname, ad_entry( &nad.ad, ADEID_NAME ), 
 
415
            ad_getentrylen( &nad.ad, ADEID_NAME ));
 
416
    nad.macname[ ad_getentrylen( &nad.ad, ADEID_NAME ) ] = '\0';
 
417
    strcpy( fh->name, nad.macname );
 
418
 
 
419
    /* just in case there's nothing in macname */
 
420
    if (*fh->name == '\0')
 
421
      strcpy(fh->name, utompath(nad.adpath[DATA]));
 
422
 
 
423
    if ( stat( nad.adpath[ DATA ], &st ) < 0 ) {
 
424
        perror( "stat of datafork failed" );
 
425
        return( -1 );
 
426
    }
 
427
    fh->forklen[ DATA ] = htonl( st.st_size );
 
428
    fh->forklen[ RESOURCE ] = htonl( ad_getentrylen( &nad.ad, ADEID_RFORK ));
 
429
    fh->comment[0] = '\0';
 
430
 
 
431
#if DEBUG
 
432
    fprintf( stderr, "macname of file\t\t\t%.*s\n", strlen( fh->name ), 
 
433
            fh->name );
 
434
    fprintf( stderr, "size of data fork\t\t%d\n", 
 
435
            ntohl( fh->forklen[ DATA ] ));
 
436
    fprintf( stderr, "size of resource fork\t\t%d\n", 
 
437
            ntohl( fh->forklen[ RESOURCE ] ));
 
438
    fprintf( stderr, "get info comment\t\t\"%s\"\n", fh->comment );
 
439
#endif /* DEBUG */
 
440
 
 
441
    ad_getdate(&nad.ad, AD_DATE_CREATE, &temptime);
 
442
    memcpy( &fh->create_date, &temptime, sizeof( temptime ));
 
443
    ad_getdate(&nad.ad, AD_DATE_MODIFY, &temptime);
 
444
    memcpy( &fh->mod_date, &temptime, sizeof( temptime ));
 
445
    ad_getdate(&nad.ad, AD_DATE_BACKUP, &temptime);
 
446
    memcpy( &fh->backup_date, &temptime, sizeof( temptime ));
 
447
 
 
448
#if DEBUG
 
449
    memcpy( &temptime, &fh->create_date, sizeof( temptime ));
 
450
    temptime = AD_DATE_TO_UNIX(temptime);
 
451
    fprintf( stderr, "create_date seconds\t\t%lu\n", temptime );
 
452
    memcpy( &temptime, &fh->mod_date, sizeof( temptime ));
 
453
    temptime = AD_DATE_TO_UNIX(temptime);
 
454
    fprintf( stderr, "mod_date seconds\t\t%lu\n", temptime );
 
455
    memcpy( &temptime, &fh->backup_date, sizeof( temptime ));
 
456
    temptime = AD_DATE_TO_UNIX(temptime);
 
457
    fprintf( stderr, "backup_date seconds\t\t%lu\n", temptime );
 
458
    fprintf( stderr, "size of finder_info\t\t%d\n", sizeof( fh->finder_info ));
 
459
#endif /* DEBUG */
 
460
 
 
461
    memcpy(&fh->finder_info.fdType,
 
462
            ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_TYPE,
 
463
           sizeof( fh->finder_info.fdType ));
 
464
    memcpy(&fh->finder_info.fdCreator,
 
465
           ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_CREATOR,
 
466
           sizeof( fh->finder_info.fdCreator ));
 
467
    memcpy(&fh->finder_info.fdFlags,
 
468
           ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_FLAGS,
 
469
           sizeof( fh->finder_info.fdFlags ));
 
470
    memcpy(&fh->finder_info.fdLocation,
 
471
           ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_LOC,
 
472
           sizeof( fh->finder_info.fdLocation ));
 
473
    memcpy(&fh->finder_info.fdFldr,
 
474
          ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_FLDR,
 
475
          sizeof( fh->finder_info.fdFldr ));
 
476
    memcpy(&fh->finder_xinfo.fdScript,
 
477
           ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_SCRIPT,
 
478
           sizeof(fh->finder_xinfo.fdScript));
 
479
    memcpy(&fh->finder_xinfo.fdXFlags,
 
480
           ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_XFLAGS,
 
481
           sizeof(fh->finder_xinfo.fdXFlags));
 
482
 
 
483
#if DEBUG
 
484
    {
 
485
        short           flags;
 
486
        fprintf( stderr, "finder_info.fdType\t\t%.*s\n", 
 
487
                sizeof( fh->finder_info.fdType ), &fh->finder_info.fdType );
 
488
        fprintf( stderr, "finder_info.fdCreator\t\t%.*s\n", 
 
489
                sizeof( fh->finder_info.fdCreator ),
 
490
                &fh->finder_info.fdCreator );
 
491
        fprintf( stderr, "nad type and creator\t\t%.*s\n\n", 
 
492
                sizeof( fh->finder_info.fdType ) + 
 
493
                sizeof( fh->finder_info.fdCreator ), 
 
494
                ad_entry( &nad.ad, ADEID_FINDERI ));
 
495
        memcpy(&flags, ad_entry( &nad.ad, ADEID_FINDERI ) + 
 
496
               FINDERIOFF_FLAGS, sizeof( flags ));
 
497
        fprintf( stderr, "nad.ad flags\t\t\t%x\n", flags );
 
498
        fprintf( stderr, "fh flags\t\t\t%x\n", fh->finder_info.fdFlags );
 
499
        fprintf(stderr, "fh script\t\t\t%x\n", fh->finder_xinfo.fdScript);
 
500
        fprintf(stderr, "fh xflags\t\t\t%x\n", fh->finder_xinfo.fdXFlags);
 
501
    }
 
502
#endif /* DEBUG */
 
503
 
 
504
    nad.offset[ DATA ] = nad.offset[ RESOURCE ] = 0;
 
505
 
 
506
    return( 0 );
 
507
 
 
508
}
 
509
 
 
510
int nad_header_write( fh )
 
511
    struct FHeader      *fh;
 
512
{
 
513
    u_int32_t           temptime;
 
514
 
 
515
    ad_setentrylen( &nad.ad, ADEID_NAME, strlen( nad.macname ));
 
516
    memcpy( ad_entry( &nad.ad, ADEID_NAME ), nad.macname, 
 
517
            ad_getentrylen( &nad.ad, ADEID_NAME ));
 
518
    ad_setentrylen( &nad.ad, ADEID_COMMENT, strlen( fh->comment ));
 
519
    memcpy( ad_entry( &nad.ad, ADEID_COMMENT ), fh->comment, 
 
520
            ad_getentrylen( &nad.ad, ADEID_COMMENT ));
 
521
    ad_setentrylen( &nad.ad, ADEID_RFORK, ntohl( fh->forklen[ RESOURCE ] ));
 
522
 
 
523
#if DEBUG
 
524
    fprintf( stderr, "ad_getentrylen\n" );
 
525
    fprintf( stderr, "ADEID_FINDERI\t\t\t%d\n", 
 
526
            ad_getentrylen( &nad.ad, ADEID_FINDERI ));
 
527
    fprintf( stderr, "ADEID_RFORK\t\t\t%d\n", 
 
528
            ad_getentrylen( &nad.ad, ADEID_RFORK ));
 
529
    fprintf( stderr, "ADEID_NAME\t\t\t%d\n",
 
530
            ad_getentrylen( &nad.ad, ADEID_NAME ));
 
531
    fprintf( stderr, "ad_entry of ADEID_NAME\t\t%.*s\n",
 
532
            ad_getentrylen( &nad.ad, ADEID_NAME ), 
 
533
            ad_entry( &nad.ad, ADEID_NAME ));
 
534
    fprintf( stderr, "ADEID_COMMENT\t\t\t%d\n",
 
535
             ad_getentrylen( &nad.ad, ADEID_COMMENT ));
 
536
#endif /* DEBUG */
 
537
 
 
538
    memcpy( &temptime, &fh->create_date, sizeof( temptime ));
 
539
    ad_setdate(&nad.ad, AD_DATE_CREATE, temptime);
 
540
    memcpy( &temptime, &fh->mod_date, sizeof( temptime ));
 
541
    ad_setdate(&nad.ad, AD_DATE_MODIFY, temptime);
 
542
 
 
543
#if DEBUG
 
544
    ad_getdate(&nad.ad, AD_DATE_CREATE, &temptime);
 
545
    temptime = AD_DATE_TO_UNIX(temptime);
 
546
    fprintf(stderr, "FILEIOFF_CREATE seconds\t\t%ld\n", temptime );
 
547
    ad_getdate(&nad.ad, AD_DATE_MODIFY, &temptime);
 
548
    temptime = AD_DATE_TO_UNIX(temptime);
 
549
    fprintf(stderr, "FILEIOFF_MODIFY seconds\t\t%ld\n", temptime );
 
550
#endif /* DEBUG */
 
551
 
 
552
    memset( ad_entry( &nad.ad, ADEID_FINDERI ), 0, ADEDLEN_FINDERI );
 
553
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_TYPE, 
 
554
            &fh->finder_info.fdType, sizeof( fh->finder_info.fdType ));
 
555
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_CREATOR,
 
556
           &fh->finder_info.fdCreator, sizeof( fh->finder_info.fdCreator ));
 
557
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_FLAGS,
 
558
            &fh->finder_info.fdFlags, sizeof( fh->finder_info.fdFlags ));
 
559
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_LOC,
 
560
            &fh->finder_info.fdLocation,sizeof( fh->finder_info.fdLocation ));
 
561
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_FLDR,
 
562
            &fh->finder_info.fdFldr, sizeof( fh->finder_info.fdFldr ));
 
563
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_SCRIPT,
 
564
            &fh->finder_xinfo.fdScript, sizeof( fh->finder_xinfo.fdScript ));
 
565
    memcpy( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_XFLAGS,
 
566
            &fh->finder_xinfo.fdXFlags, sizeof( fh->finder_xinfo.fdXFlags));
 
567
 
 
568
 
 
569
#if DEBUG
 
570
    {
 
571
        short           flags;
 
572
        memcpy(&flags, ( ad_entry( &nad.ad, ADEID_FINDERI ) + FINDERIOFF_FLAGS),
 
573
                sizeof( flags ));
 
574
        fprintf( stderr, "nad.ad flags\t\t\t%x\n", flags );
 
575
        fprintf( stderr, "fh flags\t\t\t%x\n", fh->finder_info.fdFlags );
 
576
        fprintf( stderr, "fh xflags\t\t\t%x\n", fh->finder_xinfo.fdXFlags );
 
577
        fprintf( stderr, "type and creator\t\t%.*s\n\n", 
 
578
                sizeof( fh->finder_info.fdType ) + 
 
579
                sizeof( fh->finder_info.fdCreator ),
 
580
                ad_entry( &nad.ad, ADEID_FINDERI ));
 
581
    }
 
582
#endif /* DEBUG */
 
583
 
 
584
#if HEXOUTPUT
 
585
    hexfork[ DATA ] = open( "datafork", O_WRONLY|O_CREAT, 0622 );
 
586
    hexfork[ RESOURCE ] = open( "resfork", O_WRONLY|O_CREAT, 0622 );
 
587
#endif /* HEXOUTPUT */
 
588
 
 
589
    nad.offset[ DATA ] = nad.offset[ RESOURCE ] = 0;
 
590
    ad_flush( &nad.ad, ADFLAGS_DF|ADFLAGS_HF );
 
591
 
 
592
    return( 0 );
 
593
}
 
594
 
 
595
int                     forkeid[] = { ADEID_DFORK, ADEID_RFORK };
 
596
 
 
597
int nad_read( fork, forkbuf, bufc )
 
598
    int                 fork;
 
599
    char                *forkbuf;
 
600
    int                 bufc;
 
601
{
 
602
    int                 cc = 0;
 
603
 
 
604
#if DEBUG
 
605
    fprintf( stderr, "Entering nad_read\n" );
 
606
#endif /* DEBUG */
 
607
 
 
608
    if (( cc = ad_read( &nad.ad, forkeid[ fork ], nad.offset[ fork ], 
 
609
            forkbuf, bufc)) < 0 )  {
 
610
        perror( "Reading the appledouble file:" );
 
611
        return( cc );
 
612
    }
 
613
    nad.offset[ fork ] += cc;
 
614
 
 
615
#if DEBUG
 
616
    fprintf( stderr, "Exiting nad_read\n" );
 
617
#endif /* DEBUG */
 
618
 
 
619
    return( cc );
 
620
}
 
621
 
 
622
int nad_write( fork, forkbuf, bufc )
 
623
    int                 fork;
 
624
    char                *forkbuf;
 
625
    int                 bufc;
 
626
{
 
627
    char                *buf_ptr;
 
628
    int                 writelen;
 
629
    int                 cc = 0;
 
630
 
 
631
#if DEBUG
 
632
    fprintf( stderr, "Entering nad_write\n" );
 
633
#endif /* DEBUG */
 
634
 
 
635
#if HEXOUTPUT
 
636
    write( hexfork[ fork ], forkbuf, bufc );
 
637
#endif /* HEXOUTPUT */
 
638
 
 
639
    writelen = bufc;
 
640
    buf_ptr = forkbuf;
 
641
 
 
642
    while (( writelen > 0 ) && ( cc >= 0 )) {
 
643
        cc =  ad_write( &nad.ad, forkeid[ fork ], nad.offset[ fork ], 
 
644
                0, buf_ptr, writelen);
 
645
        nad.offset[ fork ] += cc;
 
646
        buf_ptr += cc;
 
647
        writelen -= cc;
 
648
    }
 
649
    if ( cc < 0 ) {
 
650
        perror( "Writing the appledouble file:" );
 
651
        return( cc );
 
652
    }
 
653
 
 
654
    return( bufc );
 
655
}
 
656
 
 
657
int nad_close( status )
 
658
int                     status;
 
659
{
 
660
    int                 rv;
 
661
    if ( status == KEEP ) {
 
662
        if (( rv = ad_flush( &nad.ad, ADFLAGS_DF|ADFLAGS_HF )) < 0 ) {
 
663
            fprintf( stderr, "nad_close rv for flush %d\n", rv );
 
664
            return( rv );
 
665
        }
 
666
        if (( rv = ad_close( &nad.ad, ADFLAGS_DF|ADFLAGS_HF )) < 0 ) {
 
667
            fprintf( stderr, "nad_close rv for close %d\n", rv );
 
668
            return( rv );
 
669
        }
 
670
    } else if ( status == TRASH ) {
 
671
        if ( unlink( nad.adpath[ 0 ] ) < 0 ) {
 
672
            perror ( nad.adpath[ 0 ] );
 
673
        }
 
674
        if ( unlink( nad.adpath[ 1 ] ) < 0 ) {
 
675
            perror ( nad.adpath[ 1 ] );
 
676
        }
 
677
        return( 0 );
 
678
    } else return( -1 );
 
679
    return( 0 );
 
680
}