00001
00002
00003
00004
00010
00011
00012 #define MAX_FEEDS 32
00013 #define MAX_FSETS MAX_FEEDS
00014
00018 static char *ks_feeds[MAX_FEEDS];
00022 static char *ks_feedsets[MAX_FSETS];
00026 static int ks_feeds_length;
00030 static int ks_feedsets_length;
00034 static const char *ks_hostname;
00038 static const char *ks_port;
00042 static const char *argv0;
00043
00044 #ifdef HAVE_CONFIG_H
00045 #include "ks_config.h"
00046 #endif
00047
00048 #ifdef HAVE_STDIO_H
00049 #include <stdio.h>
00050 #endif
00051
00052 #ifdef HAVE_STRING_H
00053 #include <string.h>
00054 #endif
00055
00056 #ifdef HAVE_STDLIB_H
00057 #include <stdlib.h>
00058 #endif
00059
00060 #ifdef HAVE_GETOPT_H
00061 #include <getopt.h>
00062 #endif
00063
00064 #ifdef HAVE_NETDB_H
00065 #include <netdb.h>
00066 #endif
00067
00068 #ifdef HAVE_NETINET_IN_H
00069 #include <netinet/in.h>
00070 #endif
00071
00072 #ifdef HAVE_ARPA_INET_H
00073 #include <arpa/inet.h>
00074 #endif
00075
00076 #include "ks_array.h"
00077 #include "ks_assoc.h"
00078 #include "ks_bparse.h"
00079 #include "ks_bquery.h"
00080 #include "ks_combination.h"
00081 #include "ks_common.h"
00082 #include "ks_fact.h"
00083 #include "ks_malloc.h"
00084 #include "ks_number.h"
00085 #include "ks_response.h"
00086 #include "ks_string.h"
00087 #include "ks_version.h"
00088 #include "ks_socket.h"
00089
00093 static void
00094 usage(void)
00095 {
00096 printf("usage: %s [options]\n", argv0);
00097 printf("Valid options:\n");
00098 printf(" -f<feedlist> Set the (string) feed names to use.\n");
00099 printf(" -F<feedsetlist> Set the (string) feedset names to use.\n");
00100 printf(" -H<host> Set the host to use (default: "
00101 KS_QUERY_HOST_DEFAULT ")\n");
00102 printf(" -P<port> Set the port to use (default: 8666)\n");
00103 printf(" -t Use TCP (default: UDP)\n");
00104 printf(" -s Single identity per query (default: multiple)\n");
00105
00106 printf(" -l<login> Set the login to use (if required, default: none)\n");
00107 printf(" -p<password> Set the password to use\n");
00108 printf(" -4 <ip4>[=tag] Add an IP4 address to the query\n");
00109 printf(" -6 <ip6>[=tag] Add an IP6 address to the query\n");
00110 printf(" -d <domain>[=tag] Add a domain name to the query\n");
00111 printf(" -e <email>[=tag] Add an email address to the query\n");
00112 printf(" -u <uri>=tag Add a URI to the query\n");
00113 printf(" -v Print version information and exit\n");
00114 }
00115
00116
00117
00118
00119 static void
00120 version(void)
00121 {
00122 printf("%s; libkarmaclient version %d.%d.%d\n", argv0,
00123 KARMA_LIB_VERSION_MAJOR, KARMA_LIB_VERSION_MINOR,
00124 KARMA_LIB_VERSION_PATCH);
00125 }
00126
00130 static void
00131 parse_item(char *fp, char *cp,
00132 const char *name,
00133 char** items, int *len, int maxlen)
00134 {
00135 char *arg = NULL;
00136 if (cp > fp) {
00137
00138 if (*len == maxlen) {
00139 fprintf(stderr, "Too many %ss. Max %ss is %d\n",
00140 name, name, maxlen);
00141 exit(1);
00142 }
00143 arg = strdup(fp);
00144 if (!arg) {
00145 fprintf(stderr, "Failed to allocate memory for %s name\n",
00146 name);
00147 exit(1);
00148 }
00149 items[(*len)++] = arg;
00150 }
00151 }
00152
00156 static void
00157 parse_items(char *optarg,
00158 const char *name,
00159 char** items, int *len, int maxlen)
00160 {
00161 char *base;
00162 char *fp;
00163 char *cp;
00164
00165 base = strdup(optarg);
00166 fp = base;
00167 for (cp = fp; *cp; cp++) {
00168 if (*cp == ',') {
00169 *cp = '\0';
00170 parse_item(fp, cp, name, items, len, maxlen);
00171 fp = cp + 1;
00172 }
00173 }
00174 parse_item(fp, cp, name, items, len, maxlen);
00175 free(base);
00176 }
00177
00181 static void
00182 print_response(ks_response_t *e)
00183 {
00184 ks_assoc_t *s;
00185 ks_string_t *r;
00186 ks_combination_t *c;
00187 ks_fact_t *f;
00188 int i;
00189
00190 if (e == NULL) {
00191 printf("Error: no packet received\n");
00192 return;
00193 }
00194
00195 r = ks_response_error(e);
00196 if (r != NULL) {
00197 printf("Error: %s\n", ks_string_get(r));
00198 return;
00199 }
00200
00201 r = ks_response_id(e);
00202 printf("Response id '%s': %ldms, %d combinations, %d facts\n",
00203 ks_string_get(r),
00204 ks_response_time(e),
00205 ks_response_combinations_size(e),
00206 ks_response_facts_length(e));
00207
00208 r = ks_response_message(e);
00209 if (r != NULL) {
00210 printf("Warning: %s\n", ks_string_get(r));
00211 }
00212
00213 s = ks_response_combinations(e);
00214 if (s != NULL) {
00215 ks_array_t *a = ks_assoc_keys(s);
00216
00217 for (i = 0; i < ks_array_length(a); i++) {
00218 r = (ks_string_t *)ks_array_get(a, i);
00219 c = (ks_combination_t *)ks_assoc_get(s,
00220 ks_string_get(r), ks_string_length(r));
00221 printf("Combiner '%s': verdict %ld (%s)\n",
00222 ks_string_get(r),
00223 ks_combination_score(c),
00224 ks_combination_data(c));
00225 }
00226
00227 ks_array_free(a);
00228 }
00229
00230 for (i = 0; i < ks_response_facts_length(e); i++) {
00231 f = ks_response_fact(e, i);
00232 if (f == NULL)
00233 printf("Fact has no data\n");
00234 else {
00235 printf("Feed '%s':", ks_fact_feed(f));
00236 if (ks_fact_identity(f) != NULL)
00237 printf(" identity '%s'", ks_fact_identity(f));
00238 printf(" opinion %ld (%s)\n",
00239 ks_fact_value(f),
00240 ks_fact_data(f));
00241 }
00242 }
00243 }
00244
00245 #ifdef HAVE_GETOPT_LONG
00246
00249 static const struct option longopts[] = {
00250 { "host", required_argument, NULL, 'H', },
00251 { "port", required_argument, NULL, 'P', },
00252
00253 { "login", required_argument, NULL, 'l', },
00254 { "pass", required_argument, NULL, 'p', },
00255
00256 { "feed", required_argument, NULL, 'f', },
00257 { "feedset", required_argument, NULL, 'F', },
00258 { "tcp", no_argument , NULL, 't', },
00259 { "single", no_argument , NULL, 's', },
00260 { "ip4", required_argument, NULL, '4', },
00261 { "ip6", required_argument, NULL, '6', },
00262 { "domain", required_argument, NULL, 'd', },
00263 { "email", required_argument, NULL, 'e', },
00264 { "uri", required_argument, NULL, 'u', },
00265 { "help", no_argument , NULL, 'h', },
00266 { "version", no_argument , NULL, 'v', },
00267 };
00268 #endif
00269
00273 static const char *shortopts="H:P:l:p:f:F:ts4:6:d:e:u:hv";
00274
00278 static ks_base_t *
00279 identry_new(const char *data, int type)
00280 {
00281 char *tag = strrchr(data, '=');
00282 ks_array_t *id = ks_array_new();
00283 if (tag != NULL)
00284 *tag++ = '\0';
00285 ks_array_add(id, (ks_base_t *)ks_string_new(data, strlen(data)));
00286 ks_array_add(id, (ks_base_t *)ks_number_new(type));
00287 if (tag != NULL)
00288 ks_array_add(id, (ks_base_t *)ks_string_new(tag, strlen(tag)));
00289 return (ks_base_t *)id;
00290 }
00291
00295 static void
00296 identry_add(ks_bquery_t *q, ks_array_t *ids, int idx)
00297 {
00298 ks_array_t *id;
00299 ks_string_t *data;
00300 ks_number_t *type;
00301 ks_string_t *tag = NULL;
00302
00303 id = (ks_array_t *)ks_array_get(ids, idx);
00304 data = (ks_string_t *)ks_array_get(id, 0);
00305 type = (ks_number_t *)ks_array_get(id, 1);
00306 if (ks_array_length(id) == 2) {
00307 ks_bquery_identity_add(q,
00308 ks_string_get(data), ks_number_get(type));
00309 }
00310 else {
00311 tag = (ks_string_t *)ks_array_get(id, 2);
00312 ks_bquery_identity_add_tagged(q,
00313 ks_string_get(data), ks_number_get(type),
00314 ks_string_get(tag));
00315 }
00316 }
00317
00326 int
00327 main(int argc, char **argv)
00328 {
00329 ks_socket_t *k = NULL;
00330 ks_bquery_t *q = NULL;
00331 ks_response_t *e = NULL;
00332 ks_array_t *ids;
00333 int proto = IPPROTO_UDP;
00334 int single = 0;
00335 char *auth[2] = { NULL, NULL };
00336
00337 char c;
00338 int i;
00339 int j;
00340
00341 ks_hostname = KS_QUERY_HOST_DEFAULT;
00342 ks_port = KS_QUERY_PORT_DEFAULT;
00343
00344 argv0 = strrchr(argv[0], '/');
00345
00346 ids = ks_array_new();
00347
00348 while ( (c =
00349 #ifdef HAVE_GETOPT_LONG
00350 getopt_long(argc, argv, shortopts, longopts, &i)
00351 #else
00352 getopt(argc, argv, shortopts)
00353 #endif
00354 ) != -1 ) {
00355 switch(c) {
00356 case 'H':
00357 ks_hostname = optarg;
00358 break;
00359 case 'P':
00360 ks_port = optarg;
00361 break;
00362 case 'f':
00363 parse_items(optarg, "feed",
00364 ks_feeds, &ks_feeds_length, MAX_FEEDS);
00365 break;
00366 case 'F':
00367 parse_items(optarg, "feedset",
00368 ks_feedsets, &ks_feedsets_length, MAX_FSETS);
00369 break;
00370 case 't':
00371 proto = IPPROTO_TCP;
00372 break;
00373 case 's':
00374 single = 1;
00375 break;
00376 case 'l':
00377 auth[0] = optarg;
00378 break;
00379 case 'p':
00380 auth[1] = optarg;
00381 break;
00382 case '4':
00383 ks_array_add(ids, identry_new(optarg, KS_IDT_IP4));
00384 break;
00385 case '6':
00386 ks_array_add(ids, identry_new(optarg, KS_IDT_IP6));
00387 break;
00388 case 'd':
00389 ks_array_add(ids, identry_new(optarg, KS_IDT_DOMAIN));
00390 break;
00391 case 'e':
00392 ks_array_add(ids, identry_new(optarg, KS_IDT_EMAIL));
00393 break;
00394 case 'u':
00395 ks_array_add(ids, identry_new(optarg, KS_IDT_URL));
00396 break;
00397 case 'h':
00398 usage();
00399 exit(0);
00400 case 'v':
00401 version();
00402 exit(0);
00403 case ':':
00404 fprintf(stderr, "Missing parameter to %c\n", optopt);
00405 exit(1);
00406 case '?':
00407 fprintf(stderr, "Unknown flag %c\n", optopt);
00408 exit(1);
00409 }
00410 }
00411 argc -= optind;
00412 argv += optind;
00413
00414 if (ks_array_length(ids) == 0)
00415 ks_array_add(ids, identry_new("127.0.0.2", KS_IDT_IP4_ADDRESS));
00416 if (ks_feeds_length == 0 && ks_feedsets_length == 0)
00417 ks_feedsets[ks_feedsets_length++] =
00418 strdup("karmasphere.email-sender");
00419
00420 k = ks_socket_new(ks_hostname, ks_port, proto);
00421 if (k == NULL) {
00422 fprintf(stderr, "Failed to create socket\n");
00423 exit(1);
00424 }
00425 if (ks_socket_connect(k) < 0) {
00426 fprintf(stderr, "Failed to connect socket\n");
00427 exit(1);
00428 }
00429
00430 ks_socket_set_auth(k, auth[0], auth[1]);
00431
00432 if (single) {
00433 for (i = 0; i < ks_array_length(ids); i++) {
00434 q = ks_bquery_new();
00435 for (j = 0 ; j < ks_feeds_length ; j++)
00436 ks_bquery_feed_add(q, ks_feeds[j]);
00437 identry_add(q, ids, i);
00438 ks_bquery_flags_set(q, KS_FL_FACTS);
00439 e = ks_socket_ask(k, q, -1);
00440 print_response(e);
00441 ks_response_free(e);
00442 ks_bquery_free(q);
00443 }
00444 }
00445 else {
00446 q = ks_bquery_new();
00447 for (i = 0 ; i < ks_feeds_length ; i++)
00448 ks_bquery_feed_add(q, ks_feeds[i]);
00449 for (i = 0; i < ks_feedsets_length; i++)
00450 ks_bquery_composite_add(q, ks_feedsets[i]);
00451 for (i = 0; i < ks_array_length(ids); i++)
00452 identry_add(q, ids, i);
00453 ks_bquery_flags_set(q, KS_FL_FACTS);
00454 e = ks_socket_ask(k, q, -1);
00455 print_response(e);
00456 if (e != NULL)
00457 ks_response_free(e);
00458 ks_bquery_free(q);
00459 }
00460
00461 ks_array_free(ids);
00462
00463 for (i = 0; i < ks_feedsets_length; i++)
00464 free(ks_feedsets[i]);
00465 for (i = 0; i < ks_feeds_length; i++)
00466 free(ks_feeds[i]);
00467
00468 ks_socket_free(k);
00469
00470 return 0;
00471 }