/** * Receive a peerinfo information message, process it and * go for more. * * @param cls closure * @param msg message received, NULL on timeout or fatal error */ static void process_notification (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_PEERINFO_NotifyContext *nc = cls; const struct InfoMessage *im; const struct GNUNET_HELLO_Message *hello; uint16_t ms; if (msg == NULL) { GNUNET_CLIENT_disconnect (nc->client); reconnect (nc, NULL); return; } ms = ntohs (msg->size); if ((ms < sizeof (struct InfoMessage)) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO)) { GNUNET_break (0); GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return; } im = (const struct InfoMessage *) msg; hello = NULL; if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader)) { hello = (const struct GNUNET_HELLO_Message *) &im[1]; if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) { GNUNET_break (0); GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return; } } LOG (GNUNET_ERROR_TYPE_DEBUG, "Received information about peer `%s' from peerinfo database\n", GNUNET_i2s (&im->peer)); nc->callback (nc->callback_cls, &im->peer, hello, NULL); receive_notifications (nc); }
/** * Transmit our init-notify request, start receiving. * * @param cls closure (our 'struct GNUNET_PEERINFO_NotifyContext') * @param size number of bytes available in buf * @param buf where the callee should write the message * @return number of bytes written to buf */ static size_t transmit_notify_request (void *cls, size_t size, void *buf) { struct GNUNET_PEERINFO_NotifyContext *nc = cls; struct NotifyMessage nm; nc->init = NULL; if (buf == NULL) { GNUNET_CLIENT_disconnect (nc->client); nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); request_notifications (nc); return 0; } GNUNET_assert (size >= sizeof (struct NotifyMessage)); nm.header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY); nm.header.size = htons (sizeof (struct NotifyMessage)); nm.include_friend_only = htonl (nc->include_friend_only); memcpy (buf, &nm, sizeof (struct NotifyMessage)); receive_notifications (nc); return sizeof (struct NotifyMessage); }
int main(int argc, char * const *argv) { int result = 0; int do_help = 0; int do_interactive = 0; int do_leaks = 0; int ch; /* Remember my name. */ prog_name = strrchr(argv[0], '/'); prog_name = prog_name ? prog_name + 1 : argv[0]; /* Do getopt stuff for global options. */ optind = 1; optreset = 1; while ((ch = getopt(argc, argv, "hilp:qvR")) != -1) { switch (ch) { case 'h': do_help = 1; break; case 'i': do_interactive = 1; break; case 'l': do_leaks = 1; break; case 'p': do_interactive = 1; prompt_string = optarg; break; case 'q': do_quiet = 1; break; case 'v': do_verbose = 1; break; case 'R': // "Recovery mode", do NOT ask security-checksystem to run when using keychain APIs // NOTE: this is a hidden option (not in the usage message) SecKeychainSystemKeychainCheckWouldDeadlock(); break; case '?': default: return usage(); } } argc -= optind; argv += optind; if (do_help) { /* Munge argc/argv so that argv[0] is something. */ return help(argc + 1, argv - 1); } else if (argc > 0) { receive_notifications(); result = execute_command(argc, argv); receive_notifications(); } else if (do_interactive) { /* In interactive mode we just read commands and run them until readline returns NULL. */ /* Only show prompt string if stdin is a tty. */ int show_prompt = isatty(0); for (;;) { static char buffer[MAX_LINE_LEN]; char * const *av, *input; int ac; if (show_prompt) fprintf(stderr, "%s", prompt_string); input = readline(buffer, MAX_LINE_LEN); if (!input) break; split_line(input, &ac, &av); receive_notifications(); result = execute_command(ac, av); receive_notifications(); if (result == -1) { result = 0; break; } if (result && ! do_quiet) { fprintf(stderr, "%s: returned %d\n", av[0], result); } } } else result = usage(); if (do_leaks) { char *const argvec[3] = { "leaks", "-nocontext", NULL }; leaks(2, argvec); } return result; }