예제 #1
0
파일: notify.c 프로젝트: torkve/elliptics
int main(int argc, char *argv[])
{
	int ch, err, have_remote = 0, i;
	struct dnet_node *n = NULL;
	struct dnet_config cfg, rem;
	int max_id_idx = 1000, id_idx = 0, group_id = 0;
	unsigned char id[max_id_idx][DNET_ID_SIZE];
	char *logfile = "/dev/stderr", *notify_file = "/dev/stdout";
	FILE *log = NULL, *notify;

	memset(&cfg, 0, sizeof(struct dnet_config));

	cfg.sock_type = SOCK_STREAM;
	cfg.proto = IPPROTO_TCP;
	cfg.wait_timeout = 60*60;
	notify_logger.log_mask = DNET_LOG_ERROR | DNET_LOG_INFO;

	memcpy(&rem, &cfg, sizeof(struct dnet_config));

	while ((ch = getopt(argc, argv, "g:m:w:l:I:a:r:h")) != -1) {
		switch (ch) {
			case 'm':
				notify_logger.log_mask = strtoul(optarg, NULL, 0);
				break;
			case 'w':
				cfg.wait_timeout = atoi(optarg);
				break;
			case 'L':
				notify_file = optarg;
				break;
			case 'l':
				logfile = optarg;
				break;
			case 'I':
				if (id_idx < max_id_idx) {
					err = dnet_parse_numeric_id(optarg, id[id_idx]);
					if (err)
						return err;
					id_idx++;
				}
				break;
			case 'g':
				group_id = atoi(optarg);
				break;
			case 'a':
				err = dnet_parse_addr(optarg, &cfg);
				if (err)
					return err;
				break;
			case 'r':
				err = dnet_parse_addr(optarg, &rem);
				if (err)
					return err;
				have_remote = 1;
				break;
			case 'h':
			default:
				notify_usage(argv[0]);
				return -1;
		}
	}

	if (!id_idx) {
		fprintf(stderr, "No ID specified to watch.\n");
		return -EINVAL;
	}

	if (!have_remote) {
		fprintf(stderr, "No remote node specified to route requests.\n");
		return -ENOENT;
	}

	log = fopen(logfile, "a");
	if (!log) {
		err = -errno;
		fprintf(stderr, "Failed to open log file %s: %s.\n", logfile, strerror(errno));
		return err;
	}

	notify_logger.log_private = log;
	notify_logger.log = dnet_common_log;
	cfg.log = &notify_logger;

	notify = fopen(notify_file, "a");
	if (!notify) {
		err = -errno;
		fprintf(stderr, "Failed to open notify file %s: %s.\n", notify_file, strerror(errno));
		return err;
	}

	n = dnet_node_create(&cfg);
	if (!n)
		return -1;

	err = dnet_add_state(n, &rem);
	if (err)
		return err;

	for (i=0; i<id_idx; ++i) {
		struct dnet_id raw;
		dnet_setup_id(&raw, group_id, id[i]);
		err = dnet_request_notification(n, &raw, notify_complete, notify);
	}

	while (1) {
		sleep(1);
	}

	return 0;
}
예제 #2
0
static void cmd_notify(struct server *server, char *cmd_str)
{
	int opt, i;
	char *argvbuf[516];
	char **argv = argvbuf;
	int argc = 1;
	uint16_t handle;
	char *endptr = NULL;
	int length;
	uint8_t *value = NULL;
	bool indicate = false;

	if (!parse_args(cmd_str, 514, argv + 1, &argc)) {
		printf("Too many arguments\n");
		notify_usage();
		return;
	}

	optind = 0;
	argv[0] = "notify";
	while ((opt = getopt_long(argc, argv, "+i", notify_options,
								NULL)) != -1) {
		switch (opt) {
		case 'i':
			indicate = true;
			break;
		default:
			notify_usage();
			return;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1) {
		notify_usage();
		return;
	}

	handle = strtol(argv[0], &endptr, 16);
	if (!endptr || *endptr != '\0' || !handle) {
		printf("Invalid handle: %s\n", argv[0]);
		return;
	}

	length = argc - 1;

	if (length > 0) {
		if (length > UINT16_MAX) {
			printf("Value too long\n");
			return;
		}

		value = malloc(length);
		if (!value) {
			printf("Failed to construct value\n");
			return;
		}

		for (i = 1; i < argc; i++) {
			if (strlen(argv[i]) != 2) {
				printf("Invalid value byte: %s\n",
								argv[i]);
				goto done;
			}

			value[i-1] = strtol(argv[i], &endptr, 16);
			if (endptr == argv[i] || *endptr != '\0'
							|| errno == ERANGE) {
				printf("Invalid value byte: %s\n",
								argv[i]);
				goto done;
			}
		}
	}

	if (indicate) {
		if (!bt_gatt_server_send_indication(server->gatt, handle,
							value, length,
							conf_cb, NULL, NULL))
			printf("Failed to initiate indication\n");
	} else if (!bt_gatt_server_send_notification(server->gatt, handle,
								value, length))
		printf("Failed to initiate notification\n");

done:
	free(value);
}