2 * Copyright 1998 The University of Newcastle upon Tyne
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose other than its commercial exploitation
6 * is hereby granted without fee, provided that the above copyright
7 * notice appear in all copies and that both that copyright notice and
8 * this permission notice appear in supporting documentation, and that
9 * the name of The University of Newcastle upon Tyne not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. The University of
12 * Newcastle upon Tyne makes no representations about the suitability of
13 * this software for any purpose. It is provided "as is" without express
14 * or implied warranty.
16 * THE UNIVERSITY OF NEWCASTLE UPON TYNE DISCLAIMS ALL WARRANTIES WITH
17 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF
19 * NEWCASTLE UPON TYNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
21 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
25 * Author: Gerry Tomlinson (gerry.tomlinson@newcastle.ac.uk)
26 * Computing Science Department, University of Newcastle upon Tyne, UK
34 * show creator/type of netatalk file
36 * usage afile [-a] file ....
38 * looks for MAGIC at start to see if an AppleDouble else assumes it's a
39 * data fork and only reports if corresponding .AppleDouble exists unless -a option set
40 * in which case report unknown if not a directory (does not look for
43 * returns exit status 0 if all files have corresponding readable valid .AppleDouble or data fork
45 * if both parts of file don't exist in correct form it returns (for last file):
47 * 1 file doesn't exist
48 * 2 file is unreadable
50 * 4 file is AppleDouble without data fork
51 * 5 file is AppleDouble with unreadable data fork
52 * 6 file is data fork without AppleDouble
53 * 7 file is data fork with unreadable AppleDouble
54 * 8 file is data for with short AppleDouble
55 * 9 bad magic in AppleDouble
56 * 99 bad command line options
58 * by gerry.tomlinson@ncl.ac.uk
67 #include <sys/types.h>
68 #include <netinet/in.h>
72 #include <atalk/adouble.h>
76 extern int optind, opterr;
78 #define AD ".AppleDouble"
80 main(int argc, char *argv[])
86 char adbuf [AD_DATASZ];
103 while ((c = getopt(argc, argv, "a")) != -1)
111 if (errflag || argc == optind) {
112 fprintf(stderr,"usage: afile [-a] file ...\n");
117 for (; optind < argc; optind++) {
121 dname = argv[optind];
123 datafork = 1; /* assume file is a data fork */
124 gotdata = 1; /* assume data fork ok */
126 if (stat(dname, &statbuf)) {
127 fprintf(stderr,"afile: %s does not exist\n",dname);
132 if ((fdata = open(dname,O_RDONLY,0)) == -1) {
133 fprintf(stderr,"afile: cannot open %s\n",dname);
138 fstat(fdata, &statbuf);
139 if (S_ISDIR(statbuf.st_mode)) {
141 printf("directory %s\n",dname);
146 if ( read(fdata,adbuf,AD_DATASZ) == AD_DATASZ) {
147 ad = (struct adouble*)adbuf;
148 if (ad->ad_magic == ntohl(AD_MAGIC)) { /* AppleDouble Header */
150 rmode = statbuf.st_mode;
152 dname = calloc(strlen(rname)+4,1);
153 slash = rindex(rname,'/');
159 strncpy(dname, rname, slash + 1 - rname);
161 strcat(dname,slash+1);
163 if (stat(dname, &statbuf)) {
164 status = 4; /* data fork doesn't exist */
166 } else if ((fdata = open(dname,O_RDONLY,0)) == -1) {
167 status = 5; /* can't open data fork for reading */
170 dmode = statbuf.st_mode;
175 dmode = statbuf.st_mode;
176 rname = calloc(strlen(dname)+strlen(AD)+2, 1);
177 slash = rindex(dname,'/');
178 strncpy(rname,dname,slash ? slash + 1 - dname : 0);
181 strcat(rname,slash ? slash+1 : dname);
183 if (stat(rname, &statbuf)) {
185 printf("unknown %s\n",dname);
190 rmode = statbuf.st_mode;
191 if ((fres = open(rname, O_RDONLY,0)) == -1) {
192 fprintf(stderr,"afile: cannot read %s\n",rname);
196 if (read(fres,adbuf,AD_DATASZ) != AD_DATASZ) {
197 fprintf(stderr,"afile: %s too small\n",rname);
202 ad = (struct adouble*)adbuf;
205 if (ad->ad_magic != ntohl(AD_MAGIC)) {
206 fprintf(stderr,"afile: bad MAGIC in %s\n",rname);
211 printf("%4.4s %4.4s %s\n",adbuf+ADEDOFF_FINDERI, adbuf+ADEDOFF_FINDERI+4,
212 datafork ? dname : rname);
216 fprintf(stderr,"afile: %s does not exist\n",dname);
218 fprintf(stderr,"afile: cannot read %s\n",dname);
219 } else if (dmode != rmode) {
220 fprintf(stderr,"afile: %s mode does not match\n",datafork ? rname : dname);
228 /* end of program afile */