2 * Copyright (C) 2009 Sony Computer Entertainment Inc.
3 * Copyright 2009 Sony Corp.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #if defined(HAVE_CONFIG_H)
30 #include <sys/socket.h>
31 #include <sys/types.h>
34 #include "discover/user-event.h"
37 #define DBG(_args...) do {fprintf(stderr, _args); fflush(stderr); } while (0)
39 static inline int __attribute__ ((format (printf, 1, 2))) DBG(
40 __attribute__((unused)) const char *fmt, ...) {return 0; }
43 static void print_version(void)
45 printf("pb-event (" PACKAGE_NAME ") " PACKAGE_VERSION "\n");
48 static void print_usage(void)
52 "Usage: pb-event [-h] [event...]\n"
54 " Send a single petitboot user event to the petitboot discover server.\n"
55 " Events can be read from stdin, or provided on the command line.\n"
56 " User events must have the following format:\n"
58 " (add|remove|boot)@device-id [name=value] [image=value] [args=value]\n"
60 " When read from stdin, components are separated by NUL chars\n"
65 " pb-event add@/net/eth0 name=netboot image=tftp://192.168.1.10/vmlinux\n"
66 " pb-event remove@/net/eth0\n"
69 " printf 'add@/net/eth0\\0name=netboot\\0image=tftp://10.0.0.2/vmlinux\\0' \\\n"
71 " printf 'remove@/net/eth0\\0' | pb-event\n"
75 static const char *err_max_size = "pb-event: message too large "
78 static ssize_t parse_event_args(int n, char * const * args,
79 char *buf, size_t max_len)
81 ssize_t arg_len, total_len;
87 for (i = 0; i < n; i++) {
89 arg_len = strlen(arg);
91 if (total_len + (size_t)i + 1 > max_len) {
92 fprintf(stderr, err_max_size, max_len);
96 memcpy(buf + total_len, arg, arg_len);
99 buf[total_len] = '\0';
107 static ssize_t parse_event_file(FILE *filp, char *buf, size_t max_len)
111 len = fread(buf, 1, max_len, filp);
114 fprintf(stderr, err_max_size, max_len);
124 static int send_event(char *buf, ssize_t len)
126 struct sockaddr_un addr;
129 sd = socket(PF_UNIX, SOCK_DGRAM, 0);
131 err(EXIT_FAILURE, "socket");
133 memset(&addr, 0, sizeof(addr));
134 addr.sun_family = AF_UNIX;
135 strcpy(addr.sun_path, PBOOT_USER_EVENT_SOCKET);
137 for (i = 10; i; i--) {
138 ssize_t sent = sendto(sd, buf, len, 0,
139 (struct sockaddr *)&addr, SUN_LEN(&addr));
144 DBG("pb-event: waiting for server %d\n", i);
151 err(EXIT_FAILURE, "send");
153 DBG("pb-event: wrote %zu bytes\n", len);
158 int main(int argc, char *argv[])
160 char buf[PBOOT_USER_EVENT_SIZE];
163 if (argc >= 2 && !strcmp(argv[1], "-h")) {
169 len = parse_event_args(argc - 1, argv + 1,
172 len = parse_event_file(stdin, buf, sizeof(buf));
178 send_event(buf, len);