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#include <sys/param.h> 18 19#include <atalk/fce_api.h> 20#include <atalk/util.h> 21 22#define MAXBUFLEN 1024 23 24static char *fce_ev_names[] = { 25 "", 26 "FCE_FILE_MODIFY", 27 "FCE_FILE_DELETE", 28 "FCE_DIR_DELETE", 29 "FCE_FILE_CREATE", 30 "FCE_DIR_CREATE" 31}; 32 33static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet) 34{ 35 unsigned char *p = buf; 36 37 memcpy(&packet->magic[0], p, sizeof(packet->magic)); 38 p += sizeof(packet->magic); 39 40 packet->version = *p; 41 p++; 42 43 packet->mode = *p; 44 p++; 45 46 memcpy(&packet->event_id, p, sizeof(packet->event_id)); 47 p += sizeof(packet->event_id); 48 packet->event_id = ntohl(packet->event_id); 49 50 memcpy(&packet->datalen, p, sizeof(packet->datalen)); 51 p += sizeof(packet->datalen); 52 packet->datalen = ntohs(packet->datalen); 53 54 memcpy(&packet->data[0], p, packet->datalen); 55 packet->data[packet->datalen] = 0; /* 0 terminate strings */ 56 p += packet->datalen; 57 58 return 0; 59} 60 61int main(void) 62{ 63 int sockfd; 64 struct addrinfo hints, *servinfo, *p; 65 int rv; 66 int numbytes; 67 struct sockaddr_storage their_addr; 68 char buf[MAXBUFLEN]; 69 socklen_t addr_len; 70 71 memset(&hints, 0, sizeof hints); 72 hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 73 hints.ai_socktype = SOCK_DGRAM; 74 75 if ((rv = getaddrinfo(NULL, FCE_DEFAULT_PORT_STRING, &hints, &servinfo)) != 0) { 76 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 77 return 1; 78 } 79 80 // loop through all the results and bind to the first we can 81 for(p = servinfo; p != NULL; p = p->ai_next) { 82 if ((sockfd = socket(p->ai_family, p->ai_socktype, 83 p->ai_protocol)) == -1) { 84 perror("listener: socket"); 85 continue; 86 } 87 88 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 89 close(sockfd); 90 perror("listener: bind"); 91 continue; 92 } 93 94 break; 95 } 96 97 if (p == NULL) { 98 fprintf(stderr, "listener: failed to bind socket\n"); 99 return 2; 100 } 101 102 freeaddrinfo(servinfo); 103 104 printf("listener: waiting to recvfrom...\n"); 105 106 addr_len = sizeof their_addr; 107 108 struct fce_packet packet; 109 while (1) { 110 if ((numbytes = recvfrom(sockfd, 111 buf, 112 MAXBUFLEN - 1, 113 0, 114 (struct sockaddr *)&their_addr, 115 &addr_len)) == -1) { 116 perror("recvfrom"); 117 exit(1); 118 } 119 120 unpack_fce_packet((unsigned char *)buf, &packet); 121 122 if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) { 123 124 switch (packet.mode) { 125 case FCE_CONN_START: 126 printf("FCE Start\n"); 127 break; 128 129 case FCE_CONN_BROKEN: 130 printf("Broken FCE connection\n"); 131 break; 132 133 default: 134 printf("ID: %" PRIu32 ", Event: %s, Path: %s\n", 135 packet.event_id, fce_ev_names[packet.mode], packet.data); 136 break; 137 } 138 } 139 } 140 141 close(sockfd); 142 return 0; 143} 144