]> arthur.barton.de Git - netatalk.git/blob - bin/adv1tov2/adv1tov2.c
Make it working again with the new ad structure.
[netatalk.git] / bin / adv1tov2 / adv1tov2.c
1 /*
2  * $Id: adv1tov2.c,v 1.3.14.2 2004-05-08 14:12:00 didg Exp $
3  * v1tov2: given a root directory, run down and convert all the
4  * files/directories into appledouble v2.
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif /* HAVE_CONFIG_H */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <dirent.h>
14 #ifdef HAVE_FCNTL_H
15 #include <fcntl.h>
16 #endif /* HAVE_FCNTL_H */
17 #ifdef HAVE_UNISTD_H
18 #include <unistd.h>
19 #endif /* HAVE_UNISTD_H */
20 #include <ctype.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/param.h>
24
25 #include <atalk/adouble.h>
26
27 #if AD_VERSION == AD_VERSION2
28 /* translate characters */
29 static void xlate(char *name, int flags) {
30   static const char hexdig[] = "0123456789abcdef";
31   char upath[MAXPATHLEN + 1];
32   char *m, *u;
33   int doit = 0;
34
35   m = name;
36   u = upath;
37   while (*m != '\0') {
38     if (isascii(*m) && !isprint(*m)) {
39       doit = 1;
40       *u++ = ':';
41       *u++ = hexdig[(*m & 0xf0) >> 4];
42       *u++ = hexdig[*m & 0x0f];
43     } else
44       *u++ = *m;
45     m++;
46   }
47   
48   if (doit) {
49     *u = '\0';
50     rename(name, upath);
51     if ((flags & ADFLAGS_DIR) == 0)
52       rename(ad_path(name, flags), ad_path(upath, flags)); /* rename rfork */
53   }
54 }
55
56
57 #define MAXDESCEND 0xFFFF
58 /* recursively descend subdirectories. 
59  * oh the stack space we use up! */
60 void descend(DIR *dp)
61 {
62   DIR *dpnew;
63   struct dirent *de;
64   struct stat st;
65   struct adouble ad;
66   int flags;
67   static int count = 0;
68
69   ad_init(&ad, AD_VERSION2);
70   if (count++ > MAXDESCEND) {
71     fprintf(stderr, "FAILURE: too many subdirectories! possible infinite recursion.");
72     return;
73   }
74     
75   putc('(', stderr);
76   for (de = readdir(dp); de; de = readdir(dp)) {
77     if (de->d_name[0] == '.') 
78       continue;
79
80     if (stat(de->d_name, &st) < 0) {
81       fprintf(stderr, "FAILURE: can't stat %s\n", de->d_name);
82       continue;
83     }
84
85     /* go down subdirectory */
86     flags = ADFLAGS_HF;
87     if (S_ISDIR(st.st_mode) && (dpnew = opendir(de->d_name))) {
88       chdir(de->d_name);
89       descend(dpnew);
90       closedir(dpnew);
91       chdir("..");
92       flags |= ADFLAGS_DIR;
93     }
94
95     if (ad_open(de->d_name, flags, O_RDWR, 0, &ad) < 0) {
96       fprintf(stderr, "FAILURE: can't convert %s\n", de->d_name);
97       continue;
98     }
99     ad_close(&ad, ADFLAGS_HF);
100     xlate(de->d_name, flags);
101     fputc('.', stderr);
102   }
103   putc(')', stderr);
104 }
105
106
107 int main(int argc, char **argv)
108 {
109   DIR           *dp;
110   struct adouble ad;
111  
112   ad_init(&ad, AD_VERSION2);
113   if (argc != 2) {
114     fprintf(stderr, "%s <directory>\n", *argv);
115     return -1;
116   }
117     
118   /* convert main directory */
119   if (ad_open(argv[1], ADFLAGS_HF | ADFLAGS_DIR, O_RDWR, 0, 
120               &ad) < 0) {
121     fprintf(stderr, "FAILURE: can't convert %s\n", argv[1]);
122     return -1;
123   }
124
125   ad_close(&ad, ADFLAGS_HF);
126   if ((dp = opendir(argv[1])) == NULL) {
127     fprintf(stderr, "%s: unable to open %s\n", *argv, argv[1]);
128     return -1;
129   }
130
131   chdir(argv[1]);
132   descend(dp);
133   closedir(dp);
134   chdir("..");
135
136   xlate(argv[1], ADFLAGS_HF | ADFLAGS_DIR);
137   putc('\n', stderr);
138   return 0;
139 }
140
141 #else /* AD_VERSION == AD_VERSION2 */
142 int main(int argc, char **argv)
143 {
144   fprintf(stderr, "%s not built for v2 AppleDouble files.\n", *argv);
145   return -1;
146 }
147 #endif /* AD_VERSION == AD_VERSION2 */