static void key_entry_add_to_keys(key_entry_t self, int is_for_notify, elvin_keys_t keys, elvin_error_t error) { /* If this is a private key then add the raw data */ if (self->is_private) { if (!ELVIN_KEYS_ADD(keys, ELVIN_KEY_SCHEME_SHA1_DUAL, is_for_notify ? ELVIN_KEY_SHA1_DUAL_PRODUCER_INDEX : ELVIN_KEY_SHA1_DUAL_CONSUMER_INDEX, self->data, self->data_length, NULL, error)) { eeprintf(error, "elvin_keys_add failed for key %s\n", self->name); abort(); } } /* Add the hashed key data */ if (!ELVIN_KEYS_ADD(keys, ELVIN_KEY_SCHEME_SHA1_DUAL, is_for_notify ? ELVIN_KEY_SHA1_DUAL_CONSUMER_INDEX : ELVIN_KEY_SHA1_DUAL_PRODUCER_INDEX, self->hash, self->hash_length, NULL, error)) { eeprintf(error, "elvin_keys_add failed for key %s\n", self->name); abort(); } /* Add it as a producer key too */ if (!ELVIN_KEYS_ADD(keys, is_for_notify ? ELVIN_KEY_SCHEME_SHA1_CONSUMER : ELVIN_KEY_SCHEME_SHA1_PRODUCER, is_for_notify ? ELVIN_KEY_SHA1_CONSUMER_INDEX : ELVIN_KEY_SHA1_PRODUCER_INDEX, self->hash, self->hash_length, NULL, error)) { eeprintf(error, "elvin_keys_add failed for key %s\n", self->name); abort(); } }
static void key_entry_promote(key_entry_t self, int is_for_notify, elvin_keys_t keys, elvin_error_t error) { /* Sanity check */ ASSERT(self->is_private); if (!ELVIN_KEYS_ADD(keys, ELVIN_KEY_SCHEME_SHA1_DUAL, is_for_notify ? ELVIN_KEY_SHA1_DUAL_PRODUCER_INDEX : ELVIN_KEY_SHA1_DUAL_CONSUMER_INDEX, self->data, self->data_length, NULL, error)) { eeprintf(error, "elvin_keys_add failed for key %s\n", self->name); abort(); } }
int main() { eprintf(222, "%s %s\n", "This is", "cool"); eeprintf(); }
/* Parse args and go */ int main(int argc, char *argv[]) { XtAppContext context; #ifndef HAVE_XTVAOPENAPPLICATION Display *display; #endif XTickertapeRec rc; elvin_handle_t handle; elvin_error_t error; const char *user; const char *domain; const char *ticker_dir; const char *config_file; const char *groups_file; const char *usenet_file; const char *keys_file; const char *keys_dir; Widget top; const char *names[AN_MAX + 1]; int i; /* Determine the name of the executable. */ progname = xbasename(argv[0]); #ifdef HAVE_XTVAOPENAPPLICATION /* Create the toplevel widget */ top = XtVaOpenApplication( &context, "XTickertape", NULL, 0, &argc, argv, NULL, applicationShellWidgetClass, XtNborderWidth, 0, NULL); #else /* Initialize the X Toolkit */ XtToolkitInitialize(); /* Create an application context */ context = XtCreateApplicationContext(); /* Open the display */ display = XtOpenDisplay(context, NULL, NULL, "XTickertape", NULL, 0, &argc, argv); if (display == NULL) { fprintf(stderr, "Error: Can't open display\n"); exit(1); } /* Create the toplevel widget */ top = XtAppCreateShell(NULL, "XTickertape", applicationShellWidgetClass, display, NULL, 0); #endif /* Load the application shell resources */ XtGetApplicationResources(top, &rc, resources, XtNumber(resources), NULL, 0); /* Make sure our app-defaults file has a version number */ if (rc.version_tag == NULL) { app_defaults_version_error("app-defaults file not found or " "out of date"); exit(1); } /* Make sure that version number is the one we want */ if (strcmp(rc.version_tag, PACKAGE "-" VERSION) != 0) { app_defaults_version_error("app-defaults file has the wrong " "version number"); exit(1); } /* Add a calback for when it gets destroyed */ XtAppAddActions(context, actions, XtNumber(actions)); #if !defined(ELVIN_VERSION_AT_LEAST) /* Initialize the elvin client library */ error = elvin_xt_init(context); if (error == NULL) { fprintf(stderr, "*** elvin_xt_init(): failed\n"); exit(1); } /* Double-check that the initialization worked */ if (elvin_error_is_error(error)) { eeprintf(error, "elvin_xt_init failed\n"); exit(1); } /* Create a new elvin connection handle */ handle = elvin_handle_alloc(error); if (handle == NULL) { eeprintf(error, "elvin_handle_alloc failed\n"); exit(1); } #elif ELVIN_VERSION_AT_LEAST(4, 1, -1) /* Allocate an error context */ error = elvin_error_alloc(NULL, NULL); if (error == NULL) { fprintf(stderr, "%s: error: elvin_error_alloc failed\n", progname); exit(1); } /* Initialize the elvin client library */ client = elvin_xt_init_default(context, error); if (client == NULL) { eeprintf(error, "elvin_xt_init failed\n"); exit(1); } /* Create a new elvin connection handle */ handle = elvin_handle_alloc(client, error); if (handle == NULL) { eeprintf(error, "elvin_handle_alloc failed\n"); exit(1); } #else /* ELVIN_VERSION_AT_LEAST */ # error "Unsupported Elvin library version" #endif /* ELVIN_VERSION_AT_LEAST */ /* Scan what's left of the arguments */ parse_args(argc, argv, handle, &user, &domain, &ticker_dir, &config_file, &groups_file, &usenet_file, &keys_file, &keys_dir, error); /* Intern a bunch of atoms. We jump through a few hoops in order * in order to do this in a single RPC to the X server. */ #ifdef USE_ASSERT memset(names, 0, sizeof(names)); #endif /* USE_ASSERT */ for (i = 0; i <= AN_MAX; i++) { ASSERT(names[atom_list[i].index] == NULL); names[atom_list[i].index] = atom_list[i].name; } /* Make sure we've specified a name for each atom. */ for (i = 0; i <= AN_MAX; i++) { ASSERT(names[i] != NULL); } /* Intern the atoms. */ if (!XInternAtoms(XtDisplay(top), (char **)names, AN_MAX + 1, False, atoms)) { fprintf(stderr, "%s: error: XInternAtoms failed\n", progname); exit(1); } /* Create an Icon for the root shell */ XtVaSetValues(top, XtNiconWindow, create_icon(top), NULL); /* Create a tickertape */ tickertape = tickertape_alloc( &rc, handle, user, domain, ticker_dir, config_file, groups_file, usenet_file, keys_file, keys_dir, top, error); /* Set up SIGHUP to reload the subscriptions */ signal(SIGHUP, reload_subs); #ifdef USE_VALGRIND /* Set up SIGUSR1 to invoke valgrind. */ signal(SIGUSR1, count_leaks); #endif /* USE_VALGRIND */ #ifdef HAVE_LIBXMU /* Enable editres support */ XtAddEventHandler(top, (EventMask)0, True, _XEditResCheckMessages, NULL); #endif /* HAVE_LIBXMU */ /* Let 'er rip! */ XtAppMainLoop(context); /* Keep the compiler happy */ return 0; }
/* Parses arguments and sets stuff up */ static void parse_args(int argc, char *argv[], elvin_handle_t handle, const char **user_return, const char **domain_return, const char **ticker_dir_return, const char **config_file_return, const char **groups_file_return, const char **usenet_file_return, const char **keys_file_return, const char **keys_dir_return, elvin_error_t error) { const char *http_proxy = NULL; /* Initialize arguments to sane values */ *user_return = NULL; *domain_return = NULL; *ticker_dir_return = NULL; *config_file_return = NULL; *groups_file_return = NULL; *keys_file_return = NULL; *keys_dir_return = NULL; *usenet_file_return = NULL; /* Read each argument using getopt */ for (;;) { int choice; #if defined(HAVE_GETOPT_LONG) choice = getopt_long(argc, argv, OPTIONS, long_options, NULL); #else choice = getopt(argc, argv, OPTIONS); #endif /* End of options? */ if (choice < 0) { break; } /* Which option was it then? */ switch (choice) { case 'e': /* --elvin= or -e */ if (elvin_handle_append_url(handle, optarg, error) == 0) { eeprintf(error, "invalid URL: %s\n", optarg); exit(1); } break; case 'S': /* --scope= or -S */ if (!elvin_handle_set_discovery_scope(handle, optarg, error)) { eeprintf(error, "unable to set scope to %s\n", optarg); exit(1); } break; case 'H': /* --proxy= or -H */ http_proxy = optarg; break; case 'I': /* --idle= or -I */ if (!elvin_handle_set_idle_period(handle, atoi(optarg), error)) { eeprintf(error, "unable to set idle period to %s\n", optarg); exit(1); } break; case 'u': /* --user= or -u */ *user_return = optarg; break; case 'D': /* --domain= or -D */ *domain_return = strdup(optarg); break; case 'T': /* --ticker-dir= or -T */ *ticker_dir_return = optarg; break; case 'c': /* --config= or -c */ *config_file_return = optarg; break; case 'G': /* --groups= or -G */ *groups_file_return = optarg; break; case 'U': /* --usenet= or -U */ *usenet_file_return = optarg; break; case 'K': /* --keys= or -K */ *keys_file_return = optarg; break; case 'k': /* --keys-dir= or -k */ *keys_dir_return = optarg; break; case 'v': /* --version or -v */ printf(PACKAGE " version " VERSION "\n"); exit(0); case 'h': /* --help or -h */ usage(argc, argv); exit(0); default: /* Unknown option */ usage(argc, argv); exit(1); } } /* Generate a user name if none provided */ if (*user_return == NULL) { *user_return = get_user(); } /* Generate a domain name if none provided */ if (*domain_return == NULL) { *domain_return = get_domain(); } /* If we now have a proxy, then set its property */ if (http_proxy != NULL) { elvin_handle_set_string_property(handle, "http.proxy", http_proxy, NULL); } return; }
/* Delivers a notification which matches the receiver's subscription * expression */ static int notify_cb(elvin_handle_t handle, elvin_subscription_t subscription, elvin_notification_t notification, int is_secure, void *rock, elvin_error_t error) { usenet_sub_t self = (usenet_sub_t)rock; message_t message; char *string; char *newsgroups; char *name; char *subject; char *mime_type; char *mime_args; char *buffer = NULL; char *attachment = NULL; size_t length = 0; int found; /* If we don't have a callback than bail out now */ if (self->callback == NULL) { return 1; } /* Get the newsgroups to which the message was posted */ if (!elvin_notification_get_string(notification, NEWSGROUPS, &found, &string, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } /* Use a reasonable default */ string = found ? string : "news"; /* Prepend `usenet:' to the beginning of the group field */ length = strlen(USENET_PREFIX) + strlen(string) - 1; newsgroups = malloc(length); if (newsgroups == NULL) { return 0; } snprintf(newsgroups, length, USENET_PREFIX, string); /* Get the name from the FROM_NAME field (if provided) */ if (!elvin_notification_get_string(notification, FROM_NAME, &found, &name, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } if (!found) { /* No FROM_NAME field, so try FROM_EMAIL */ if (!elvin_notification_get_string(notification, FROM_EMAIL, &found, &name, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } if (!found) { /* No FROM_EMAIL, so try FROM */ if (!elvin_notification_get_string(notification, FROM, &found, &name, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } if (!found) { /* Give up */ name = "anonymous"; } } } /* Get the SUBJECT field (if provided) */ if (!elvin_notification_get_string(notification, SUBJECT, &found, &subject, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } /* Use a default if none found */ subject = found ? subject : "[no subject]"; /* Get the MIME_ARGS field (if provided) */ if (!elvin_notification_get_string(notification, MIME_ARGS, &found, &mime_args, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } /* Was the MIME_ARGS field provided? */ if (found) { /* Get the MIME_TYPE field (if provided) */ if (!elvin_notification_get_string(notification, MIME_TYPE, &found, &mime_type, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } /* Use a default if none found */ mime_type = found ? mime_type : URL_MIME_TYPE; } else { char *message_id; /* No MIME_ARGS. Look for a message-id */ if (!elvin_notification_get_string(notification, MESSAGE_ID, &found, &message_id, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } if (found) { char *news_host; /* Look up the news host field */ if (!elvin_notification_get_string( notification, X_NNTP_HOST, &found, &news_host, error)) { eeprintf(error, "elvin_notification_get_string failed\n"); exit(1); } news_host = found ? news_host : "news"; length = strlen(NEWS_URL) + strlen(news_host) + strlen(message_id) - 3; buffer = malloc(length); if (buffer == NULL) { mime_type = NULL; mime_args = NULL; } else { snprintf(buffer, length, NEWS_URL, news_host, message_id); mime_args = buffer; mime_type = NEWS_MIME_TYPE; } } else { mime_type = NULL; mime_args = NULL; } } /* Convert the mime type and args into an attachment */ if (mime_type == NULL || mime_args == NULL) { attachment = NULL; length = 0; } else { length = strlen(ATTACHMENT_FMT) - 4 + strlen(mime_type) + strlen( mime_args); attachment = malloc(length + 1); if (attachment == NULL) { length = 0; } else { snprintf(attachment, length + 1, ATTACHMENT_FMT, mime_type, mime_args); } } /* Construct a message out of all of that */ message = message_alloc(NULL, newsgroups, name, subject, 60, attachment, length, NULL, NULL, NULL, NULL); if (message != NULL) { /* Deliver the message */ self->callback(self->rock, message, False); } /* Clean up */ free(newsgroups); if (buffer != NULL) { free(buffer); } return 1; }