]> arthur.barton.de Git - netatalk.git/blob - bin/ad/ad_find.c
ad find works
[netatalk.git] / bin / ad / ad_find.c
1 /* 
2    Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
3    
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8  
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif /* HAVE_CONFIG_H */
18
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <limits.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <dirent.h>
28 #include <fcntl.h>
29 #include <ctype.h>
30 #include <pwd.h>
31 #include <grp.h>
32 #include <time.h>
33
34 #include <atalk/adouble.h>
35 #include <atalk/cnid.h>
36 #include <atalk/cnid_dbd_private.h>
37 #include <atalk/volinfo.h>
38 #include <atalk/bstrlib.h>
39 #include <atalk/bstradd.h>
40 #include <atalk/directory.h>
41 #include "ad.h"
42
43 static volatile sig_atomic_t alarmed;
44
45 /*
46   SIGNAL handling:
47   catch SIGINT and SIGTERM which cause clean exit. Ignore anything else.
48 */
49
50 static void sig_handler(int signo)
51 {
52     alarmed = 1;
53     return;
54 }
55
56 static void set_signal(void)
57 {
58     struct sigaction sv;
59
60     sv.sa_handler = sig_handler;
61     sv.sa_flags = SA_RESTART;
62     sigemptyset(&sv.sa_mask);
63     if (sigaction(SIGTERM, &sv, NULL) < 0)
64         ERROR("error in sigaction(SIGTERM): %s", strerror(errno));
65
66     if (sigaction(SIGINT, &sv, NULL) < 0)
67         ERROR("error in sigaction(SIGINT): %s", strerror(errno));
68
69     memset(&sv, 0, sizeof(struct sigaction));
70     sv.sa_handler = SIG_IGN;
71     sigemptyset(&sv.sa_mask);
72
73     if (sigaction(SIGABRT, &sv, NULL) < 0)
74         ERROR("error in sigaction(SIGABRT): %s", strerror(errno));
75
76     if (sigaction(SIGHUP, &sv, NULL) < 0)
77         ERROR("error in sigaction(SIGHUP): %s", strerror(errno));
78
79     if (sigaction(SIGQUIT, &sv, NULL) < 0)
80         ERROR("error in sigaction(SIGQUIT): %s", strerror(errno));
81 }
82
83 static void usage_find(void)
84 {
85     printf(
86         "Usage: ad find VOLUME_PATH NAME\n"
87         );
88 }
89
90 int ad_find(int argc, char **argv)
91 {
92     int c;
93     afpvol_t vol;
94
95     if (argc != 4) {
96         usage_find();
97         exit(1);
98     }
99
100     set_signal();
101     cnid_init();
102
103     if (openvol(argv[2], &vol) != 0)
104         ERROR("Cant open volume \"%s\"", argv[2]);
105
106     int count;
107     char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)];
108     if ((count = cnid_find(vol.volume.v_cdb, argv[3], strlen(argv[3]), resbuf, sizeof(resbuf))) < 1) {
109         SLOG("No results");
110     } else {
111         cnid_t cnid;
112         char *bufp = resbuf;
113         bstring sep = bfromcstr("/");
114         while (count--) {
115             memcpy(&cnid, bufp, sizeof(cnid_t));
116             bufp += sizeof(cnid_t);
117
118             bstring path = NULL;
119             bstring volpath = bfromcstr(vol.volinfo.v_path);
120             BSTRING_STRIP_SLASH(volpath);
121             char buffer[12 + MAXPATHLEN + 1];
122             int buflen = 12 + MAXPATHLEN + 1;
123             char *name;
124             cnid_t did = cnid;
125             struct bstrList *pathlist = bstrListCreateMin(32);
126
127             while (did != DIRDID_ROOT) {
128                 if ((name = cnid_resolve(vol.volume.v_cdb, &did, buffer, buflen)) == NULL)
129                     ERROR("Can't resolve CNID: %u", ntohl(did));
130                 bstrListPush(pathlist, bfromcstr(name));
131             }
132             bstrListPush(pathlist, volpath);
133             path = bjoinInv(pathlist, sep);
134             bstrListDestroy(pathlist);
135             
136             printf("%s\n", cfrombstr(path));
137             bdestroy(path);
138         }
139         bdestroy(sep);
140     }
141
142     closevol(&vol);
143
144     return 0;
145 }