static int unix_sock_change_iface(struct globals *globals, struct alfred_change_interface_v0 *change_iface, int client_sock) { int len, ret = -1; len = ntohs(change_iface->header.length); if (len < (int)(sizeof(*change_iface) - sizeof(change_iface->header))) goto err; if (globals->opmode == OPMODE_SLAVE) { if (strstr(change_iface->ifaces, ",") != NULL) { ret = -EINVAL; fprintf(stderr, "Tried to set multiple interfaces in slave mode\n"); goto err; } } netsock_set_interfaces(globals, change_iface->ifaces); ret = 0; err: close(client_sock); return ret; }
static struct globals *alfred_init(int argc, char *argv[]) { int opt, opt_ind, i, ret; struct globals *globals; struct option long_options[] = { {"set-data", required_argument, NULL, 's'}, {"request", required_argument, NULL, 'r'}, {"interface", required_argument, NULL, 'i'}, {"master", no_argument, NULL, 'm'}, {"help", no_argument, NULL, 'h'}, {"req-version", required_argument, NULL, 'V'}, {"modeswitch", required_argument, NULL, 'M'}, {"change-interface", required_argument, NULL, 'I'}, {"unix-path", required_argument, NULL, 'u'}, {"update-command", required_argument, NULL, 'c'}, {"version", no_argument, NULL, 'v'}, {"verbose", no_argument, NULL, 'd'}, {NULL, 0, NULL, 0}, }; ret = reduce_capabilities(); if (ret < 0) return NULL; globals = &alfred_globals; memset(globals, 0, sizeof(*globals)); INIT_LIST_HEAD(&globals->interfaces); globals->change_interface = NULL; globals->opmode = OPMODE_SLAVE; globals->clientmode = CLIENT_NONE; globals->best_server = NULL; globals->clientmode_version = 0; globals->mesh_iface = "bat0"; globals->unix_path = ALFRED_SOCK_PATH_DEFAULT; globals->verbose = 0; globals->update_command = NULL; INIT_LIST_HEAD(&globals->changed_data_types); globals->changed_data_type_count = 0; time_random_seed(); while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:M:I:u:dc:", long_options, &opt_ind)) != -1) { switch (opt) { case 'r': globals->clientmode = CLIENT_REQUEST_DATA; i = atoi(optarg); if (i < ALFRED_MAX_RESERVED_TYPE || i > 255) { fprintf(stderr, "bad data type argument\n"); return NULL; } globals->clientmode_arg = i; break; case 's': globals->clientmode = CLIENT_SET_DATA; i = atoi(optarg); if (i < ALFRED_MAX_RESERVED_TYPE || i > 255) { fprintf(stderr, "bad data type argument\n"); return NULL; } globals->clientmode_arg = i; break; case 'm': globals->opmode = OPMODE_MASTER; break; case 'i': netsock_set_interfaces(globals, optarg); break; case 'b': globals->mesh_iface = strdup(optarg); break; case 'V': i = atoi(optarg); if (i < 0 || i > 255) { fprintf(stderr, "bad data version argument\n"); return NULL; } globals->clientmode_version = atoi(optarg); break; case 'M': if (strcmp(optarg, "master") == 0) { globals->opmode = OPMODE_MASTER; } else if (strcmp(optarg, "slave") == 0) { globals->opmode = OPMODE_SLAVE; } else { fprintf(stderr, "bad modeswitch argument\n"); return NULL; } globals->clientmode = CLIENT_MODESWITCH; break; case 'I': globals->clientmode = CLIENT_CHANGE_INTERFACE; globals->change_interface = strdup(optarg); break; case 'u': globals->unix_path = optarg; break; case 'd': globals->verbose++; break; case 'c': globals->update_command = optarg; break; case 'v': printf("%s %s\n", argv[0], SOURCE_VERSION); printf("A.L.F.R.E.D. - Almighty Lightweight Remote Fact Exchange Daemon\n"); return NULL; case 'h': default: alfred_usage(); return NULL; } } if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) perror("could not register SIGPIPE handler"); if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) perror("could not register SIGCHLD handler"); return globals; }