]> arthur.barton.de Git - netatalk.git/blob - bin/misc/fce.c
Remove bdb env on exit
[netatalk.git] / bin / misc / fce.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif /* HAVE_CONFIG_H */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <netdb.h>
15 #include <inttypes.h>
16 #include <sys/types.h>
17
18 #include <sys/param.h>
19 #include <sys/cdefs.h>
20
21 #include <atalk/fce_api.h>
22 #include <atalk/util.h>
23
24 #define MAXBUFLEN 1024
25
26 static char *fce_ev_names[] = {
27     "",
28     "FCE_FILE_MODIFY",
29     "FCE_FILE_DELETE",
30     "FCE_DIR_DELETE",
31     "FCE_FILE_CREATE",
32     "FCE_DIR_CREATE",
33     "FCE_TM_SIZE"
34 };
35
36 // get sockaddr, IPv4 or IPv6:
37 static void *get_in_addr(struct sockaddr *sa)
38 {
39     if (sa->sa_family == AF_INET) {
40         return &(((struct sockaddr_in*)sa)->sin_addr);
41     }
42
43     return &(((struct sockaddr_in6*)sa)->sin6_addr);
44 }
45
46 static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet)
47 {
48     unsigned char *p = buf;
49
50     memcpy(&packet->magic[0], p, sizeof(packet->magic));
51     p += sizeof(packet->magic);
52
53     packet->version = *p;
54     p++;
55
56     packet->mode = *p;
57     p++;
58
59     memcpy(&packet->event_id, p, sizeof(packet->event_id));
60     p += sizeof(packet->event_id);
61     packet->event_id = ntohl(packet->event_id);
62
63     memcpy(&packet->datalen, p, sizeof(packet->datalen));
64     p += sizeof(packet->datalen);
65     packet->datalen = ntohs(packet->datalen);
66
67     memcpy(&packet->data[0], p, packet->datalen);
68     p += packet->datalen;
69
70     return 0;
71 }
72
73 int main(void)
74 {
75     int sockfd;
76     struct addrinfo hints, *servinfo, *p;
77     int rv;
78     int numbytes;
79     struct sockaddr_storage their_addr;
80     char buf[MAXBUFLEN];
81     socklen_t addr_len;
82     char s[INET6_ADDRSTRLEN];
83     uint64_t tmsize;
84
85     memset(&hints, 0, sizeof hints);
86     hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
87     hints.ai_socktype = SOCK_DGRAM;
88
89     if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) {
90         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
91         return 1;
92     }
93
94     // loop through all the results and bind to the first we can
95     for(p = servinfo; p != NULL; p = p->ai_next) {
96         if ((sockfd = socket(p->ai_family, p->ai_socktype,
97                              p->ai_protocol)) == -1) {
98             perror("listener: socket");
99             continue;
100         }
101
102         if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
103             close(sockfd);
104             perror("listener: bind");
105             continue;
106         }
107
108         break;
109     }
110
111     if (p == NULL) {
112         fprintf(stderr, "listener: failed to bind socket\n");
113         return 2;
114     }
115
116     freeaddrinfo(servinfo);
117
118     printf("listener: waiting to recvfrom...\n");
119
120     addr_len = sizeof their_addr;
121
122     struct fce_packet packet;
123     while (1) {
124         if ((numbytes = recvfrom(sockfd,
125                                  buf,
126                                  MAXBUFLEN - 1,
127                                  0,
128                                  (struct sockaddr *)&their_addr,
129                                  &addr_len)) == -1) {
130             perror("recvfrom");
131             exit(1);
132         }
133
134         unpack_fce_packet(buf, &packet);
135
136         if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) {
137
138             switch (packet.mode) {
139             case FCE_TM_SIZE:
140                 memcpy(&tmsize, packet.data, sizeof(uint64_t));
141                 tmsize = ntoh64(tmsize);
142                 printf("ID: %" PRIu32 ", Event: %s, Volume: %s, TM used size: %" PRIu64 " \n",
143                        packet.event_id, fce_ev_names[packet.mode], packet.data + sizeof(uint64_t), tmsize);
144                 break;
145
146             case FCE_CONN_START:
147                 printf("FCE Start\n");
148                 break;
149
150             case FCE_CONN_BROKEN:
151                 printf("Broken FCE connection\n");
152                 break;
153
154             default:
155                 printf("ID: %" PRIu32 ", Event: %s, Path: %s\n",
156                        packet.event_id, fce_ev_names[packet.mode], packet.data);
157                 break;
158             }
159         }
160     }
161
162     close(sockfd);
163     return 0;
164 }