static json_t * derive(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *hdr, json_t *cek, const json_t *key) { const jose_hook_alg_t *halg = NULL; const char *name = alg->name; uint8_t pu[KEYMAX] = {}; uint8_t pv[KEYMAX] = {}; uint8_t dk[KEYMAX] = {}; uint8_t ky[KEYMAX] = {}; const char *enc = NULL; json_t *out = NULL; size_t dkl = 0; size_t pul = 0; size_t pvl = 0; size_t kyl = 0; halg = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_HASH, "S256"); if (!halg) goto egress; if (json_unpack(hdr, "{s?s}", "enc", &enc) < 0) goto egress; if (!enc && json_unpack(cek, "{s:s}", "alg", &enc) < 0) goto egress; switch (str2enum(alg->name, NAMES, NULL)) { case 0: dkl = encr_alg_keylen(cfg, enc); name = enc; break; case 1: dkl = 16; break; case 2: dkl = 24; break; case 3: dkl = 32; break; default: goto egress; } if (dkl < 16 || dkl > sizeof(dk)) goto egress; pul = decode(hdr, "apu", pu, sizeof(pu)); if (pul > sizeof(pu)) goto egress; pvl = decode(hdr, "apv", pv, sizeof(pv)); if (pvl > sizeof(pv)) goto egress; kyl = decode(key, "x", ky, sizeof(ky)); if (kyl > sizeof(ky)) goto egress; if (!concatkdf(halg, cfg, dk, dkl, ky, kyl, name, strlen(name), pu, pul, pv, pvl, NULL)) goto egress; out = json_pack("{s:s,s:s,s:o}", "kty", "oct", "alg", enc, "k", jose_b64_enc(dk, dkl)); egress: OPENSSL_cleanse(ky, sizeof(ky)); OPENSSL_cleanse(pu, sizeof(pu)); OPENSSL_cleanse(pv, sizeof(pv)); OPENSSL_cleanse(dk, sizeof(dk)); return out; }
/* subscribe /root subname {query} * Subscribes the client connection to the specified root. */ static void cmd_subscribe(struct watchman_client *clientbase, json_t *args) { w_root_t *root; struct watchman_client_subscription *sub; json_t *resp; json_t *jfield_list; json_t *jname; w_query *query; json_t *query_spec; struct w_query_field_list field_list; char *errmsg; int defer = true; /* can't use bool because json_unpack requires int */ json_t *defer_list = NULL; json_t *drop_list = NULL; struct watchman_user_client *client = (struct watchman_user_client *)clientbase; if (json_array_size(args) != 4) { send_error_response(&client->client, "wrong number of arguments for subscribe"); return; } root = resolve_root_or_err(&client->client, args, 1, true); if (!root) { return; } jname = json_array_get(args, 2); if (!json_is_string(jname)) { send_error_response(&client->client, "expected 2nd parameter to be subscription name"); goto done; } query_spec = json_array_get(args, 3); jfield_list = json_object_get(query_spec, "fields"); if (!parse_field_list(jfield_list, &field_list, &errmsg)) { send_error_response(&client->client, "invalid field list: %s", errmsg); free(errmsg); goto done; } query = w_query_parse(root, query_spec, &errmsg); if (!query) { send_error_response(&client->client, "failed to parse query: %s", errmsg); free(errmsg); goto done; } json_unpack(query_spec, "{s?:o}", "defer", &defer_list); if (defer_list && !json_is_array(defer_list)) { send_error_response(&client->client, "defer field must be an array of strings"); goto done; } json_unpack(query_spec, "{s?:o}", "drop", &drop_list); if (drop_list && !json_is_array(drop_list)) { send_error_response(&client->client, "drop field must be an array of strings"); goto done; } sub = calloc(1, sizeof(*sub)); if (!sub) { send_error_response(&client->client, "no memory!"); goto done; } sub->name = json_to_w_string_incref(jname); sub->query = query; json_unpack(query_spec, "{s?:b}", "defer_vcs", &defer); sub->vcs_defer = defer; if (drop_list || defer_list) { size_t i; sub->drop_or_defer = w_ht_new(2, &w_ht_string_funcs); if (defer_list) { for (i = 0; i < json_array_size(defer_list); i++) { w_ht_replace(sub->drop_or_defer, w_ht_ptr_val(json_to_w_string_incref( json_array_get(defer_list, i))), false); } } if (drop_list) { for (i = 0; i < json_array_size(drop_list); i++) { w_ht_replace(sub->drop_or_defer, w_ht_ptr_val(json_to_w_string_incref(json_array_get(drop_list, i))), true); } } } memcpy(&sub->field_list, &field_list, sizeof(field_list)); sub->root = root; pthread_mutex_lock(&w_client_lock); w_ht_replace(client->subscriptions, w_ht_ptr_val(sub->name), w_ht_ptr_val(sub)); pthread_mutex_unlock(&w_client_lock); resp = make_response(); annotate_with_clock(root, resp); json_incref(jname); set_prop(resp, "subscribe", jname); add_root_warnings_to_response(resp, root); send_and_dispose_response(&client->client, resp); resp = build_subscription_results(sub, root); if (resp) { send_and_dispose_response(&client->client, resp); } done: w_root_delref(root); }
int hackerboatStateClass::parseTimeSpec (json_t *input, timespec *t) { return json_unpack(input, "{s:i,s:i}", "tv_sec", &(t->tv_sec), "tv_nsec", &(t->tv_nsec)); }
/* subscribe /root subname {query} * Subscribes the client connection to the specified root. */ static void cmd_subscribe(struct watchman_client *client, json_t *args) { w_root_t *root; struct watchman_client_subscription *sub; json_t *resp; const char *name; json_t *jfield_list; w_query *query; json_t *query_spec; struct w_query_field_list field_list; char *errmsg; int defer = true; /* can't use bool because json_unpack requires int */ if (json_array_size(args) != 4) { send_error_response(client, "wrong number of arguments for subscribe"); return; } root = resolve_root_or_err(client, args, 1, true); if (!root) { return; } name = json_string_value(json_array_get(args, 2)); if (!name) { send_error_response(client, "expected 2nd parameter to be subscription name"); goto done; } query_spec = json_array_get(args, 3); jfield_list = json_object_get(query_spec, "fields"); if (!parse_field_list(jfield_list, &field_list, &errmsg)) { send_error_response(client, "invalid field list: %s", errmsg); free(errmsg); goto done; } query = w_query_parse(root, query_spec, &errmsg); if (!query) { send_error_response(client, "failed to parse query: %s", errmsg); free(errmsg); goto done; } sub = calloc(1, sizeof(*sub)); if (!sub) { send_error_response(client, "no memory!"); goto done; } sub->name = w_string_new(name); sub->query = query; json_unpack(query_spec, "{s?:b}", "defer_vcs", &defer); sub->vcs_defer = defer; memcpy(&sub->field_list, &field_list, sizeof(field_list)); sub->root = root; pthread_mutex_lock(&w_client_lock); w_ht_replace(client->subscriptions, w_ht_ptr_val(sub->name), w_ht_ptr_val(sub)); pthread_mutex_unlock(&w_client_lock); resp = make_response(); annotate_with_clock(root, resp); set_prop(resp, "subscribe", json_string(name)); add_root_warnings_to_response(resp, root); send_and_dispose_response(client, resp); resp = build_subscription_results(sub, root); if (resp) { send_and_dispose_response(client, resp); } done: w_root_delref(root); }
static void spawn_command( const std::shared_ptr<w_root_t>& root, struct watchman_trigger_command* cmd, w_query_res* res, struct w_clockspec* since_spec) { char **envp = NULL; uint32_t i = 0; int ret; char **argv = NULL; uint32_t env_size; posix_spawn_file_actions_t actions; posix_spawnattr_t attr; #ifndef _WIN32 sigset_t mask; #endif long arg_max; size_t argspace_remaining; bool file_overflow = false; int result_log_level; w_string_t *working_dir = NULL; #ifdef _WIN32 arg_max = 32*1024; #else arg_max = sysconf(_SC_ARG_MAX); #endif if (arg_max <= 0) { argspace_remaining = UINT_MAX; } else { argspace_remaining = (uint32_t)arg_max; } // Allow some misc working overhead argspace_remaining -= 32; // Record an overflow before we call prepare_stdin(), which mutates // and resizes the results to fit the specified limit. if (cmd->max_files_stdin > 0 && res->resultsArray.array().size() > cmd->max_files_stdin) { file_overflow = true; } auto stdin_file = prepare_stdin(cmd, res); if (!stdin_file) { w_log( W_LOG_ERR, "trigger %s:%s %s\n", root->root_path.c_str(), cmd->triggername.c_str(), strerror(errno)); return; } // Assumption: that only one thread will be executing on a given // cmd instance so that mutation of cmd->envht is safe. // This is guaranteed in the current architecture. // It is way too much of a hassle to try to recreate the clock value if it's // not a relative clock spec, and it's only going to happen on the first run // anyway, so just skip doing that entirely. if (since_spec && since_spec->tag == w_cs_clock) { w_envp_set_cstring( cmd->envht, "WATCHMAN_SINCE", since_spec->clock.position.toClockString().c_str()); } else { w_envp_unset(cmd->envht, "WATCHMAN_SINCE"); } w_envp_set_cstring( cmd->envht, "WATCHMAN_CLOCK", res->clockAtStartOfQuery.toClockString().c_str()); if (cmd->query->relative_root) { w_envp_set(cmd->envht, "WATCHMAN_RELATIVE_ROOT", cmd->query->relative_root); } else { w_envp_unset(cmd->envht, "WATCHMAN_RELATIVE_ROOT"); } // Compute args auto args = json_deep_copy(cmd->command); if (cmd->append_files) { // Measure how much space the base args take up for (i = 0; i < json_array_size(args); i++) { const char *ele = json_string_value(json_array_get(args, i)); argspace_remaining -= strlen(ele) + 1 + sizeof(char*); } // Dry run with env to compute space envp = w_envp_make_from_ht(cmd->envht, &env_size); free(envp); envp = NULL; argspace_remaining -= env_size; for (const auto& item : res->dedupedFileNames) { // also: NUL terminator and entry in argv uint32_t size = item.size() + 1 + sizeof(char*); if (argspace_remaining < size) { file_overflow = true; break; } argspace_remaining -= size; json_array_append_new(args, w_string_to_json(item)); } } argv = w_argv_copy_from_json(args, 0); args = nullptr; w_envp_set_bool(cmd->envht, "WATCHMAN_FILES_OVERFLOW", file_overflow); envp = w_envp_make_from_ht(cmd->envht, &env_size); posix_spawnattr_init(&attr); #ifndef _WIN32 sigemptyset(&mask); posix_spawnattr_setsigmask(&attr, &mask); #endif posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK| #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT // Darwin: close everything except what we put in file actions POSIX_SPAWN_CLOEXEC_DEFAULT| #endif POSIX_SPAWN_SETPGROUP); posix_spawn_file_actions_init(&actions); #ifndef _WIN32 posix_spawn_file_actions_adddup2( &actions, stdin_file->getFileDescriptor(), STDIN_FILENO); #else posix_spawn_file_actions_adddup2_handle_np( &actions, stdin_file->getWindowsHandle(), STDIN_FILENO); #endif if (cmd->stdout_name) { posix_spawn_file_actions_addopen(&actions, STDOUT_FILENO, cmd->stdout_name, cmd->stdout_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDOUT_FILENO); } if (cmd->stderr_name) { posix_spawn_file_actions_addopen(&actions, STDERR_FILENO, cmd->stderr_name, cmd->stderr_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDERR_FILENO, STDERR_FILENO); } // Figure out the appropriate cwd { const char *cwd = NULL; working_dir = NULL; if (cmd->query->relative_root) { working_dir = cmd->query->relative_root; } else { working_dir = root->root_path; } w_string_addref(working_dir); json_unpack(cmd->definition, "{s:s}", "chdir", &cwd); if (cwd) { w_string_t *cwd_str = w_string_new_typed(cwd, W_STRING_BYTE); if (w_is_path_absolute_cstr(cwd)) { w_string_delref(working_dir); working_dir = cwd_str; } else { w_string_t *joined; joined = w_string_path_cat(working_dir, cwd_str); w_string_delref(cwd_str); w_string_delref(working_dir); working_dir = joined; } } w_log(W_LOG_DBG, "using %.*s for working dir\n", working_dir->len, working_dir->buf); } #ifndef _WIN32 // This mutex is present to avoid fighting over the cwd when multiple // triggers run at the same time. It doesn't coordinate with all // possible chdir() calls, but this is the only place that we do this // in the watchman server process. static std::mutex cwdMutex; { std::unique_lock<std::mutex> lock(cwdMutex); ignore_result(chdir(working_dir->buf)); #else posix_spawnattr_setcwd_np(&attr, working_dir->buf); #endif w_string_delref(working_dir); working_dir = nullptr; ret = posix_spawnp(&cmd->current_proc, argv[0], &actions, &attr, argv, envp); if (ret != 0) { // On Darwin (at least), posix_spawn can fail but will still populate the // pid. Since we use the pid to gate future spawns, we need to ensure // that we clear out the pid on failure, otherwise the trigger would be // effectively disabled for the rest of the watch lifetime cmd->current_proc = 0; } #ifndef _WIN32 ignore_result(chdir("/")); } #endif // If failed, we want to make sure we log enough info to figure out why result_log_level = res == 0 ? W_LOG_DBG : W_LOG_ERR; w_log(result_log_level, "posix_spawnp: %s\n", cmd->triggername.c_str()); for (i = 0; argv[i]; i++) { w_log(result_log_level, "argv[%d] %s\n", i, argv[i]); } for (i = 0; envp[i]; i++) { w_log(result_log_level, "envp[%d] %s\n", i, envp[i]); } w_log( result_log_level, "trigger %s:%s pid=%d ret=%d %s\n", root->root_path.c_str(), cmd->triggername.c_str(), (int)cmd->current_proc, ret, strerror(ret)); free(argv); free(envp); posix_spawnattr_destroy(&attr); posix_spawn_file_actions_destroy(&actions); }
/* * main() * * @function DronePi Application main * */ int main(int argc, char* argv[]) { //yaw pid int count; char ff; int cnt=0; int ycnt=0; //network about int tcp,udp; int flag,str_len,t=0; double x = 0,y=0,z=0; double pp,pi,pd; char pidbuf[100],tcp_flag,recv_flag; json_t *data; json_error_t error; // Yaw PID 상수 double yp,yi,yd; // Roll, Pitch PID 상수 double kp, ki, kd; // 모터 출력량 int throttle = 0; // 상대좌표 Yaw를 사용하기위한 보정 값 float adjustYaw=0.f; // Quardcopter 로 모터 4개 선언 Motor motor[4]; // imu 장치 MPU6050 선언 IMU imu; for(int i = 0 ; i < 4 ; i++) { motor[i].init(); } // Setting Pin to Raspberry pi gpio motor[0].setPin(22); motor[1].setPin(23); motor[2].setPin(24); motor[3].setPin(25); // ESC Calibration motor[0].calibration(); motor[1].calibration(); motor[2].calibration(); motor[3].calibration(); if(imu.init()) { printf("Plese check the MPU6050 device connection!!\n"); return 0; //센서 연결 실패 } // PID 연산을 위한 각 축의 PID 연산자 객체 선언 PID rollPid, pitchPid, yawPid; rollPid.init(); pitchPid.init(); yawPid.init(); kp = 2.0; // 1.2 ki = 0.1; // 0.00084 kd = 0.85; // 0.6134 rollPid.setTuning(2.0, 0.1, 0.78); pitchPid.setTuning(2.0, 0.1, 0.78); yawPid.setTuning(10.0, 0.f, 10.0); float roll, pitch, yaw, preYaw, rYaw; int pidRoll, pidPitch, pidYaw; // 자이로센서 init 및 calibration imu.calibration(); int Motor1_speed, Motor2_speed, Motor3_speed, Motor4_speed; printf("Connect Application!!\n"); // Network init if(network_init(&tcp,&udp)==-1) { printf("socket create error\n"); return 0; } printf("network init complete\n"); // 급격한 각도변화 발생시 비상제어. 착륙 실행 flag int Emergency = 0; // 상대 Yaw 좌표 preYaw = 0; /* * Drone Control routine * * 1. 조작 데이터 수신 * 2. 현재 각도 측정 * 3. PID 연산 * 4. 모터 속도 업데이트 * */ while(1) { // Get json data from android app flag=json_read(udp,&x,&y,&z,&t); if(flag==1) { throttle = t; } // 2. 현재 각도 측정 imu.getIMUData(&roll, &pitch, &yaw); // 센서 오류 및 오동작으로 인한 동작 방지 // 특정 각도 이상으로 기울어지면 종료할 수 있도록 함 if( pitch < -50 || pitch > 50 || roll < -50 || roll > 50) { Emergency = 1; } // 상대 Yaw 연산 if(preYaw>100&&yaw<-100) rYaw=360+yaw-preYaw; else if(preYaw<-100&&yaw>100) rYaw=360-yaw+preYaw; else rYaw= yaw - preYaw; if(ycnt==33) { printf("rYaw: %.2lf preYaw: %.2lf yaw: %.2lf\n",rYaw,preYaw,yaw); ycnt=0; } ycnt++; preYaw = yaw; // 각 축의 PID 연산 pidRoll = rollPid.calcPID(x, roll); pidPitch = pitchPid.calcPID(-y, pitch); pidYaw = yawPid.calcPID(0, rYaw-z); // Quardcopter type X 의 모터 속도 연산 Motor1_speed = throttle + pidRoll + pidPitch + pidYaw; Motor2_speed = throttle - pidRoll + pidPitch - pidYaw; Motor3_speed = throttle - pidRoll - pidPitch + pidYaw; Motor4_speed = throttle + pidRoll - pidPitch - pidYaw; if(cnt==33) { printf("X: %.2lf Y: %.2lf Z: %.2lf T:%d \n",x,y,z,t); printf("ROLL : %3.6f, PITCH %3.7f, YAW %3.7f\n", roll, pitch, yaw); printf("pidRoll : %d, pidPitch : %d pidYaw: %d\n", pidRoll,pidPitch,pidYaw); printf("motor speed [1]:%d [2]:%d [3]:%d [4]:%d\n\n\n", Motor1_speed, Motor2_speed, Motor3_speed, Motor4_speed); cnt=0; } cnt++; if(Emergency) { // 긴급상황. 모터속도 최소화 Motor1_speed = 700; Motor2_speed = 700; Motor3_speed = 700; Motor4_speed = 700; } if(Motor1_speed < 700) Motor1_speed = 700; if(Motor2_speed < 700) Motor2_speed = 700; if(Motor3_speed < 700) Motor3_speed = 700; if(Motor4_speed < 700) Motor4_speed = 700; // 모터 속도 업데이트 motor[0].setSpeed(Motor1_speed); motor[1].setSpeed(Motor2_speed); motor[2].setSpeed(Motor3_speed); motor[3].setSpeed(Motor4_speed); tcp_flag=tcp_read(tcp); if(tcp_flag==3) { motor[0].setSpeed(700); motor[1].setSpeed(700); motor[2].setSpeed(700); motor[3].setSpeed(700); memset(pidbuf,0,sizeof(pidbuf)); printf("pid reset flag\n"); str_len=recv(tcp,pidbuf,sizeof(pidbuf),MSG_DONTROUTE); pidbuf[str_len]=0; printf("pid reset data :%s\n",pidbuf); data=json_loads(pidbuf,JSON_DECODE_ANY,&error); if((json_unpack(data,"{s:f,s:f,s:f,s:f,s:f,s:f}","P_P",&pp,"P_I",&pi,"P_D",&pd,"Y_P",&yp,"Y_I",&yi,"Y_D",&yd))!=0) { printf("pid reset error\n"); recv_flag=0; send(tcp,&recv_flag,1,MSG_DONTROUTE); return 0; } recv_flag=1; send(tcp,&recv_flag,1,MSG_DONTROUTE); rollPid.initKpid(pp, pi, pd); pitchPid.initKpid(pp, pi, pd); yawPid.initKpid(yp, yi, yd); Emergency=0; printf("pid reset complete\n"); } else if(tcp_flag==5) { motor[0].setSpeed(700); motor[1].setSpeed(700); motor[2].setSpeed(700); motor[3].setSpeed(700); printf("drone exit\n"); break; } else if(tcp_flag==0) { motor[0].setSpeed(700); motor[1].setSpeed(700); motor[2].setSpeed(700); motor[3].setSpeed(700); printf("Controller connection less\n"); break; } }//end while(1) sleep(3); }//end int main()
static int do_connect(const char *host, int port, const char *user, const char *pass, const char *email, int reg_user, int connid) { int fd = -1, authresult, copylen; char ipv6_error[120], ipv4_error[120], errmsg[256]; json_t *jmsg, *jarr; #ifdef UNIX /* try to connect to a local unix socket */ struct sockaddr_un sun; sun.sun_family = AF_UNIX; copylen = strlen(host) + 1; if (copylen > sizeof(sun.sun_path) - 1) copylen = sizeof(sun.sun_path) - 1; memcpy(sun.sun_path, host, copylen); sun.sun_path[sizeof(sun.sun_path) - 1] = '\0'; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd >= 0) { if (connect(fd, (struct sockaddr*)&sun, sizeof(sun)) == -1) { close(fd); fd = -1; } } #endif /* try ipv6 */ if (fd == -1) fd = connect_server(host, port, FALSE, ipv6_error, 120); if (fd == -1) /* no ipv6 connection, try ipv4 */ fd = connect_server(host, port, TRUE, ipv4_error, 120); if (fd == -1) { /* both connection attempts failed: error message */ if (!ipv6_error[0] && !ipv4_error[0]) { snprintf(errmsg, 256, "No address for \"%s\" found!", host); print_error(errmsg); } if (ipv6_error[0]) { snprintf(errmsg, 256, "IPv6: %s", ipv6_error); print_error(errmsg); } if (ipv4_error[0]) { snprintf(errmsg, 256, "IPv4: %s", ipv4_error); print_error(errmsg); } return NO_CONNECTION; } in_connect_disconnect = TRUE; sockfd = fd; jmsg = json_pack("{ss,ss}", "username", user, "password", pass); if (reg_user) { if (email) json_object_set_new(jmsg, "email", json_string(email)); jmsg = send_receive_msg("register", jmsg); } else { if (connid) json_object_set_new(jmsg, "reconnect", json_integer(connid)); jmsg = send_receive_msg("auth", jmsg); } in_connect_disconnect = FALSE; if (!jmsg || json_unpack(jmsg, "{si,si*}", "return", &authresult, "connection", &connection_id) == -1) { if (jmsg) json_decref(jmsg); close(fd); return NO_CONNECTION; } /* the "version" field in the response is optional */ if (json_unpack(jmsg, "{so*}", "version", &jarr) != -1 && json_is_array(jarr) && json_array_size(jarr) >= 3) { nhnet_server_ver.major = json_integer_value(json_array_get(jarr, 0)); nhnet_server_ver.minor = json_integer_value(json_array_get(jarr, 1)); nhnet_server_ver.patchlevel = json_integer_value(json_array_get(jarr, 2)); } json_decref(jmsg); if (host != saved_hostname) strncpy(saved_hostname, host, sizeof(saved_hostname)); if (user != saved_username) strncpy(saved_username, user, sizeof(saved_username)); if (pass != saved_password) strncpy(saved_password, pass, sizeof(saved_password)); saved_port = port; conn_err = FALSE; net_active = TRUE; return authresult; }
struct nh_drawing_info *nhnet_get_drawing_info(void) { json_t *jmsg, *jbg, *jtraps, *jobjs, *jmons, *jwarn, *jexpt, *jzapt, *jzaps, *jeff, *jexps, *jswal, *jinvis; struct nh_drawing_info *di; if (!nhnet_active()) return nh_get_drawing_info(); if (!api_entry()) return 0; jmsg = send_receive_msg("get_drawing_info", json_object()); di = xmalloc(sizeof(struct nh_drawing_info)); if (json_unpack(jmsg, "{si,si,si,si,si,si,si,si,si,so,so,so,so,so,so,so,so,so,so,so,so!}", "num_bgelements", &di->num_bgelements, "num_traps", &di->num_traps, "num_objects", &di->num_objects, "num_monsters", &di->num_monsters, "num_warnings", &di->num_warnings, "num_expltypes", &di->num_expltypes, "num_zaptypes", &di->num_zaptypes, "num_effects", &di->num_effects, "feature_offset", &di->bg_feature_offset, "bgelements", &jbg, "traps", &jtraps, "objects", &jobjs, "monsters", &jmons, "warnings", &jwarn, "expltypes", &jexpt, "zaptypes", &jzapt, "effects", &jeff, "explsyms", &jexps, "zapsyms", &jzaps, "swallowsyms", &jswal, "invis", &jinvis) == -1 || !json_is_array(jbg) || !json_is_array(jobjs) || !json_is_array(jmons) || !json_is_array(jwarn) || !json_is_array(jexpt) || !json_is_array(jzapt) || !json_is_array(jeff) || !json_is_array(jexps) || !json_is_array(jswal) || !json_is_array(jinvis)) { print_error("Incorrect return object in nhnet_get_drawing_info"); di = NULL; } else { di->bgelements = read_symdef_array(jbg); di->traps = read_symdef_array(jtraps); di->objects = read_symdef_array(jobjs); di->monsters = read_symdef_array(jmons); di->warnings = read_symdef_array(jwarn); di->expltypes = read_symdef_array(jexpt); di->zaptypes = read_symdef_array(jzapt); di->effects = read_symdef_array(jeff); di->explsyms = read_symdef_array(jexps); di->zapsyms = read_symdef_array(jzaps); di->swallowsyms = read_symdef_array(jswal); di->invis = read_symdef_array(jinvis); } json_decref(jmsg); api_exit(); return di; }
static void read_json_option(json_t *jobj, struct nh_option_desc *opt) { json_t *joptval, *joptdesc, *jelem; const char *name, *helptxt, *strval; int size, i; struct nh_autopickup_rule *r; memset(opt, 0, sizeof(struct nh_option_desc)); if (!json_unpack(jobj, "{ss,ss,si,so,so!}", "name", &name, "helptxt", &helptxt, "type", &opt->type, "value", &joptval, "desc", &joptdesc) == -1) { memset(opt, 0, sizeof(struct nh_option_desc)); print_error("Broken option specification."); return; } opt->name = strdup(name); opt->helptxt = strdup(helptxt); switch (opt->type) { case OPTTYPE_BOOL: opt->value.b = json_integer_value(joptval); break; case OPTTYPE_INT: opt->value.i = json_integer_value(joptval); json_unpack(joptdesc, "{si,si!}", "max", &opt->i.max, "min", &opt->i.min); break; case OPTTYPE_ENUM: opt->value.e = json_integer_value(joptval); size = json_array_size(joptdesc); opt->e.numchoices = size; opt->e.choices = read_json_list(joptdesc); break; case OPTTYPE_STRING: opt->value.s = strdup(json_string_value(joptval)); opt->s.maxlen = json_integer_value(joptdesc); break; case OPTTYPE_AUTOPICKUP_RULES: size = json_array_size(joptdesc); opt->a.numclasses = size; opt->a.classes = read_json_list(joptdesc); size = json_array_size(joptval); if (!size) break; opt->value.ar = malloc(sizeof(struct nh_autopickup_rules)); opt->value.ar->num_rules = size; opt->value.ar->rules = malloc(size * sizeof(struct nh_autopickup_rule)); for (i = 0; i < size; i++) { r = &opt->value.ar->rules[i]; jelem = json_array_get(joptval, i); json_unpack(jelem, "{ss,si,si,si!}", "pattern", &strval, "oclass", &r->oclass, "buc", &r->buc, "action", &r->action); strncpy(r->pattern, strval, sizeof(r->pattern) - 1); } break; } }
if (!actual_json) return -ENOMEM; /* * Create json objects for all present ports */ teamd_for_each_tdport(tdport, ctx) { err = get_port_obj(NULL, actual_json, tdport->ifname); if (err) goto errout; } /* * Get rid of json object of ports which are not present */ err = json_unpack(actual_json, "{s:o}", "ports", &ports_obj); if (!err) { iter = json_object_iter(ports_obj); while (iter) { const char *port_name = json_object_iter_key(iter); iter = json_object_iter_next(ports_obj, iter); if (!teamd_get_port_by_ifname(ctx, (char *) port_name)) json_object_del(ports_obj, port_name); } } dump = json_dumps(actual_json, TEAMD_JSON_DUMPS_FLAGS); json_decref(actual_json); if (!dump) return -ENOMEM;
static json_t * cmd_update_screen(json_t * params, int display_only) { static struct nh_dbuf_entry dbuf[ROWNO][COLNO]; int ux, uy; int x, y, effect, bg, trap, obj, obj_mn, mon, monflags, branding, invis, visible; json_t *jdbuf, *col, *elem; if (json_unpack(params, "{si,si,so!}", "ux", &ux, "uy", &uy, "dbuf", &jdbuf) == -1) { print_error("Incorrect parameters in cmd_update_screen"); return NULL; } if (json_is_integer(jdbuf)) { if (json_integer_value(jdbuf) == 0) { memset(dbuf, 0, sizeof (struct nh_dbuf_entry) * ROWNO * COLNO); cur_wndprocs.win_update_screen(dbuf, ux, uy); } else print_error("Incorrect parameter in cmd_update_screen"); return NULL; } if (!json_is_array(jdbuf)) { print_error("Incorrect parameter in cmd_update_screen"); return NULL; } if (json_array_size(jdbuf) != COLNO) print_error("Wrong number of columns in cmd_update_screen"); for (x = 0; x < COLNO; x++) { col = json_array_get(jdbuf, x); if (json_is_integer(col)) { if (json_integer_value(col) == 0) { for (y = 0; y < ROWNO; y++) memset(&dbuf[y][x], 0, sizeof (struct nh_dbuf_entry)); } else if (json_integer_value(col) != 1) print_error("Strange column value in cmd_update_screen"); continue; } if (!json_is_array(col) || json_array_size(col) != ROWNO) { print_error("Wrong column data type in cmd_update_screen"); continue; } for (y = 0; y < ROWNO; y++) { elem = json_array_get(col, y); if (json_is_integer(elem)) { if (json_integer_value(elem) == 0) memset(&dbuf[y][x], 0, sizeof (struct nh_dbuf_entry)); else if (json_integer_value(elem) != 1) print_error("Strange element value in cmd_update_screen"); continue; } if (json_unpack (elem, "[i,i,i,i,i,i,i,i,i,i!]", &effect, &bg, &trap, &obj, &obj_mn, &mon, &monflags, &branding, &invis, &visible) == -1) print_error("Strange element data in cmd_update_screen"); dbuf[y][x].effect = effect; dbuf[y][x].bg = bg; dbuf[y][x].trap = trap; dbuf[y][x].obj = obj; dbuf[y][x].obj_mn = obj_mn; dbuf[y][x].mon = mon; dbuf[y][x].monflags = monflags; dbuf[y][x].branding = branding; dbuf[y][x].invis = invis; dbuf[y][x].visible = visible; } } cur_wndprocs.win_update_screen(dbuf, ux, uy); return NULL; }
vmlist *qvd_list_of_vm(qvdclient *qvd) { char url[MAX_BASEURL]; int i; long http_code = 0; json_error_t error; char *command = "/qvd/list_of_vm"; if (!_qvd_set_certdir(qvd)) { qvd_printf("Please set the cert dir"); return NULL; } if (qvd->home && (*(qvd->home)) != '\0') { qvd_printf("Setting NX_HOME to %s\n", qvd->home); if (setenv("NX_HOME", qvd->home, 1)) { qvd_error(qvd, "Error setting NX_HOME to %s. errno: %d (%s)", qvd->home, errno, strerror(errno)); } } if (snprintf(url, MAX_BASEURL, "%s%s", qvd->baseurl, command) >= MAX_BASEURL) { qvd_error(qvd, "Error initializing url in list_of_vm, length is longer than %d\n", MAX_BASEURL); return NULL; } _qvd_use_client_cert(qvd); curl_easy_setopt(qvd->curl, CURLOPT_URL, url); /* curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonBuffer); */ qvd->res = curl_easy_perform(qvd->curl); qvd_printf("After easy_perform: %ul\n", qvd->res); if (qvd->res) { qvd_printf("Error accessing url: <%s>, error code: %ul\n", url, qvd->res); qvd_error(qvd, "Error accessing list of VMs: %s\n", curl_easy_strerror(qvd->res)); return NULL; } curl_easy_getinfo (qvd->curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code == 401) { qvd_error(qvd, "Error authenticating user\n"); return NULL; } qvd_printf("No error and no auth error after curl_easy_perform\n"); /* QvdBufferInit(&(qvd->buffer)); */ json_t *vmList = json_loads(qvd->buffer.data, 0, &error); int arrayLength = json_array_size(vmList); qvd->numvms = arrayLength; qvd_printf("VMs available: %d\n", qvd->numvms); QvdVmListFree(qvd->vmlist); if (!(qvd->vmlist = malloc(sizeof(vmlist)))) { qvd_error(qvd, "Error allocating memory for vmlist"); return NULL; } QvdVmListInit(qvd->vmlist); for (i = 0; i < arrayLength; i++) { json_t *obj = json_array_get(vmList, i); int id, blocked; char *name, *state; json_unpack(obj, "{s:i,s:s,s:i,s:s}", "id", &id, "state", &state, "blocked", &blocked, "name", &name); qvd_printf("VM ID:%d NAME:%s STATE:%s BLOCKED:%d\n", id, name, state, blocked); QvdVmListAppendVm(qvd, qvd->vmlist, QvdVmNew(id, name, state, blocked)); } /* QvdBufferReset(&(qvd->buffer));*/ if (qvd->numvms <= 0) { qvd_error(qvd, "No virtual machines available for user %s\n", qvd->username); } else { qvd_progress(qvd, "Returning list of vms"); } return qvd->vmlist; }
struct nhnet_game * nhnet_list_games(int done, int show_all, int *count) { int i, has_amulet; json_t *jmsg, *jarr, *jobj; struct nhnet_game *gb; struct nhnet_game *gamebuf = NULL; const char *plname, *plrole, *plrace, *plgend, *plalign, *level_desc, *death; if (!api_entry()) return NULL; jmsg = json_pack("{si,si,si}", "limit", 0, "completed", done, "show_all", show_all); jmsg = send_receive_msg("list_games", jmsg); if (json_unpack(jmsg, "{so!}", "games", &jarr) == -1 || !json_is_array(jarr)) { print_error("Incorrect return object in nhnet_list_games"); *count = 0; } else { *count = json_array_size(jarr); gamebuf = xmalloc(*count * sizeof (struct nhnet_game)); for (i = 0; i < *count; i++) { gb = &gamebuf[i]; memset(gb, 0, sizeof (struct nhnet_game)); jobj = json_array_get(jarr, i); if (json_unpack (jobj, "{si,si,si,ss,ss,ss,ss,ss*}", "gameid", &gb->gameid, "status", &gb->status, "playmode", &gb->i.playmode, "plname", &plname, "plrole", &plrole, "plrace", &plrace, "plgend", &plgend, "plalign", &plalign) == -1) { print_error("Invalid game info object."); continue; } strncpy(gb->i.name, plname, PL_NSIZ - 1); strncpy(gb->i.plrole, plrole, PLRBUFSZ - 1); strncpy(gb->i.plrace, plrace, PLRBUFSZ - 1); strncpy(gb->i.plgend, plgend, PLRBUFSZ - 1); strncpy(gb->i.plalign, plalign, PLRBUFSZ - 1); if (gb->status == LS_SAVED) { json_unpack(jobj, "{ss,si,si,si*}", "level_desc", &level_desc, "moves", &gb->i.moves, "depth", &gb->i.depth, "has_amulet", &has_amulet); gb->i.has_amulet = has_amulet; strncpy(gb->i.level_desc, level_desc, sizeof (gb->i.level_desc) - 1); } else if (gb->status == LS_DONE) { json_unpack(jobj, "{ss,si,si*}", "death", &death, "moves", &gb->i.moves, "depth", &gb->i.depth); strncpy(gb->i.death, death, sizeof (gb->i.death) - 1); } } } json_decref(jmsg); api_exit(); return gamebuf; }
bool locationClass::parse(json_t* input) { if (json_unpack(input, "{s:F,s:F}", "latitude", &_lat, "longitude", &_lon)) { return false; } return this->isValid(); }
static void spawn_command(w_root_t *root, struct watchman_trigger_command *cmd, w_query_res *res, struct w_clockspec *since_spec) { char **envp = NULL; uint32_t i = 0; int ret; w_stm_t stdin_file = NULL; json_t *args; char **argv = NULL; uint32_t env_size; posix_spawn_file_actions_t actions; posix_spawnattr_t attr; #ifndef _WIN32 sigset_t mask; #endif long arg_max; size_t argspace_remaining; bool file_overflow = false; int result_log_level; char clockbuf[128]; w_string_t *working_dir = NULL; #ifdef _WIN32 arg_max = 32*1024; #else arg_max = sysconf(_SC_ARG_MAX); #endif if (arg_max <= 0) { argspace_remaining = UINT_MAX; } else { argspace_remaining = (uint32_t)arg_max; } // Allow some misc working overhead argspace_remaining -= 32; stdin_file = prepare_stdin(cmd, res); if (!stdin_file) { w_log(W_LOG_ERR, "trigger %.*s:%s %s\n", (int)root->root_path->len, root->root_path->buf, cmd->triggername->buf, strerror(errno)); return; } // Assumption: that only one thread will be executing on a given // cmd instance so that mutation of cmd->envht is safe. // This is guaranteed in the current architecture. if (cmd->max_files_stdin > 0 && res->num_results > cmd->max_files_stdin) { file_overflow = true; } // It is way too much of a hassle to try to recreate the clock value if it's // not a relative clock spec, and it's only going to happen on the first run // anyway, so just skip doing that entirely. if (since_spec && since_spec->tag == w_cs_clock && clock_id_string(since_spec->clock.root_number, since_spec->clock.ticks, clockbuf, sizeof(clockbuf))) { w_envp_set_cstring(cmd->envht, "WATCHMAN_SINCE", clockbuf); } else { w_envp_unset(cmd->envht, "WATCHMAN_SINCE"); } if (clock_id_string(res->root_number, res->ticks, clockbuf, sizeof(clockbuf))) { w_envp_set_cstring(cmd->envht, "WATCHMAN_CLOCK", clockbuf); } else { w_envp_unset(cmd->envht, "WATCHMAN_CLOCK"); } if (cmd->query->relative_root) { w_envp_set(cmd->envht, "WATCHMAN_RELATIVE_ROOT", cmd->query->relative_root); } else { w_envp_unset(cmd->envht, "WATCHMAN_RELATIVE_ROOT"); } // Compute args args = json_deep_copy(cmd->command); if (cmd->append_files) { // Measure how much space the base args take up for (i = 0; i < json_array_size(args); i++) { const char *ele = json_string_value(json_array_get(args, i)); argspace_remaining -= strlen(ele) + 1 + sizeof(char*); } // Dry run with env to compute space envp = w_envp_make_from_ht(cmd->envht, &env_size); free(envp); envp = NULL; argspace_remaining -= env_size; for (i = 0; i < res->num_results; i++) { // also: NUL terminator and entry in argv uint32_t size = res->results[i].relname->len + 1 + sizeof(char*); if (argspace_remaining < size) { file_overflow = true; break; } argspace_remaining -= size; json_array_append_new( args, json_string_nocheck(res->results[i].relname->buf) ); } } argv = w_argv_copy_from_json(args, 0); json_decref(args); args = NULL; w_envp_set_bool(cmd->envht, "WATCHMAN_FILES_OVERFLOW", file_overflow); envp = w_envp_make_from_ht(cmd->envht, &env_size); posix_spawnattr_init(&attr); #ifndef _WIN32 sigemptyset(&mask); posix_spawnattr_setsigmask(&attr, &mask); #endif posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK| #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT // Darwin: close everything except what we put in file actions POSIX_SPAWN_CLOEXEC_DEFAULT| #endif POSIX_SPAWN_SETPGROUP); posix_spawn_file_actions_init(&actions); #ifndef _WIN32 posix_spawn_file_actions_adddup2(&actions, w_stm_fileno(stdin_file), STDIN_FILENO); #else posix_spawn_file_actions_adddup2_handle_np(&actions, w_stm_handle(stdin_file), STDIN_FILENO); #endif if (cmd->stdout_name) { posix_spawn_file_actions_addopen(&actions, STDOUT_FILENO, cmd->stdout_name, cmd->stdout_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDOUT_FILENO); } if (cmd->stderr_name) { posix_spawn_file_actions_addopen(&actions, STDERR_FILENO, cmd->stderr_name, cmd->stderr_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDERR_FILENO, STDERR_FILENO); } // Figure out the appropriate cwd { const char *cwd = NULL; working_dir = NULL; if (cmd->query->relative_root) { working_dir = cmd->query->relative_root; } else { working_dir = root->root_path; } w_string_addref(working_dir); json_unpack(cmd->definition, "{s:s}", "chdir", &cwd); if (cwd) { w_string_t *cwd_str = w_string_new(cwd); if (w_is_path_absolute(cwd)) { w_string_delref(working_dir); working_dir = cwd_str; } else { w_string_t *joined; joined = w_string_path_cat(working_dir, cwd_str); w_string_delref(cwd_str); w_string_delref(working_dir); working_dir = joined; } } w_log(W_LOG_DBG, "using %.*s for working dir\n", working_dir->len, working_dir->buf); } pthread_mutex_lock(&spawn_lock); #ifndef _WIN32 ignore_result(chdir(working_dir->buf)); #else posix_spawnattr_setcwd_np(&attr, working_dir->buf); #endif w_string_delref(working_dir); working_dir = NULL; ret = posix_spawnp(&cmd->current_proc, argv[0], &actions, &attr, argv, envp); if (ret == 0) { w_root_addref(root); insert_running_pid(cmd->current_proc, root); } else { // On Darwin (at least), posix_spawn can fail but will still populate the // pid. Since we use the pid to gate future spawns, we need to ensure // that we clear out the pid on failure, otherwise the trigger would be // effectively disabled for the rest of the watch lifetime cmd->current_proc = 0; } #ifndef _WIN32 ignore_result(chdir("/")); #endif pthread_mutex_unlock(&spawn_lock); // If failed, we want to make sure we log enough info to figure out why result_log_level = res == 0 ? W_LOG_DBG : W_LOG_ERR; w_log(result_log_level, "posix_spawnp:\n"); for (i = 0; argv[i]; i++) { w_log(result_log_level, "argv[%d] %s\n", i, argv[i]); } for (i = 0; envp[i]; i++) { w_log(result_log_level, "envp[%d] %s\n", i, envp[i]); } w_log(result_log_level, "trigger %.*s:%s pid=%d ret=%d %s\n", (int)root->root_path->len, root->root_path->buf, cmd->triggername->buf, (int)cmd->current_proc, ret, strerror(ret)); free(argv); free(envp); posix_spawnattr_destroy(&attr); posix_spawn_file_actions_destroy(&actions); if (stdin_file) { w_stm_close(stdin_file); } }
struct nh_topten_entry *nhnet_get_topten(int *out_len, char *statusbuf, const char *player, int top, int around, nh_bool own) { struct nh_topten_entry *ttlist; json_t *jmsg, *jarr, *jobj; const char *msg, *plrole, *plrace, *plgend, *plalign, *name, *death, *entrytxt; int len, i, highlight; if (!nhnet_active()) return nh_get_topten(out_len, statusbuf, player, top, around, own); *out_len = 0; if (!api_entry()) return NULL; jmsg = json_pack("{ss,si,si,si}", "player", player ? player : "", "top", top, "around", around, "own", own); jmsg = send_receive_msg("get_topten", jmsg); if (json_unpack(jmsg, "{so,ss!}", "toplist", &jarr, "msg", &msg) == -1 || !json_is_array(jarr)) { print_error("Incorrect return object in nhnet_get_topten"); ttlist = NULL; } else { len = json_array_size(jarr); strncpy(statusbuf, msg, BUFSZ-1); *out_len = len; ttlist = xmalloc((len+1) * sizeof(struct nh_topten_entry)); memset(ttlist, 0, (len+1) * sizeof(struct nh_topten_entry)); for (i = 0; i < len; i++) { jobj = json_array_get(jarr, i); json_unpack(jobj, "{si,si,si,si,si,si,si,si,si,si,si,si,si,ss,ss,ss,ss,ss,ss,ss,si!}", "rank", &ttlist[i].rank, "points", &ttlist[i].points, "maxlvl", &ttlist[i].maxlvl, "hp", &ttlist[i].hp, "maxhp", &ttlist[i].maxhp, "deaths", &ttlist[i].deaths, "ver_major", &ttlist[i].ver_major, "ver_minor", &ttlist[i].ver_minor, "patchlevel", &ttlist[i].patchlevel, "deathdate", &ttlist[i].deathdate, "birthdate", &ttlist[i].birthdate, "moves", &ttlist[i].moves, "end_how", &ttlist[i].end_how, "plrole", &plrole, "plrace", &plrace, "plgend", &plgend, "plalign", &plalign, "name", &name, "death", &death, "entrytxt", &entrytxt, "highlight", &highlight); strncpy(ttlist[i].plrole, plrole, PLRBUFSZ - 1); strncpy(ttlist[i].plrace, plrace, PLRBUFSZ - 1); strncpy(ttlist[i].plgend, plgend, PLRBUFSZ - 1); strncpy(ttlist[i].plalign, plalign, PLRBUFSZ - 1); strncpy(ttlist[i].name, name, PL_NSIZ - 1); strncpy(ttlist[i].death, death, BUFSZ - 1); strncpy(ttlist[i].entrytxt, entrytxt, BUFSZ - 1); ttlist[i].highlight = highlight; } } json_decref(jmsg); api_exit(); return ttlist; }
static bool load_cached_shader_binary(opengl::ShaderProgram* program, SCP_string hash) { if (!do_shader_caching()) { return false; } auto base_filename = SCP_string("ogl_shader-") + hash; auto metadata = base_filename + ".json"; auto binary = base_filename + ".bin"; auto metadata_fp = cfopen(metadata.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE); if (!metadata_fp) { nprintf(("ShaderCache", "Metadata file does not exist.\n")); return false; } auto size = cfilelength(metadata_fp); SCP_string metadata_content; metadata_content.resize((size_t) size); cfread(&metadata_content[0], 1, size, metadata_fp); cfclose(metadata_fp); auto metadata_root = json_loads(metadata_content.c_str(), 0, nullptr); if (!metadata_root) { mprintf(("Loading of cache metadata failed! Falling back to GLSL shader...\n")); return false; } json_int_t format; if (json_unpack(metadata_root, "{sI}", "format", &format) != 0) { mprintf(("Failed to unpack values from metadata JSON! Falling back to GLSL shader...\n")); return false; } auto binary_format = (GLenum) format; json_decref(metadata_root); auto binary_fp = cfopen(binary.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE); if (!binary_fp) { nprintf(("ShaderCache", "Binary file does not exist.\n")); return false; } GR_DEBUG_SCOPE("Loading cached shader"); SCP_vector<uint8_t> buffer; int length = cfilelength(binary_fp); buffer.resize((size_t) length); cfread(&buffer[0], 1, length, binary_fp); cfclose(binary_fp); // Load the data! glProgramBinary(program->getShaderHandle(), binary_format, buffer.data(), (GLsizei) buffer.size()); // Check the status... GLint status; glGetProgramiv(program->getShaderHandle(), GL_LINK_STATUS, &status); return status == GL_TRUE; }
int beginSlavery(int fd) { uint16_t randContext[3]; for(int i = 0; i < 3; i++) { randContext[i] = time(NULL) ^ getpid(); } int returnCode = -1; json_t* params = NULL; json_t* nextCommand = NULL; char** values = NULL; struct workerTask* tasks = NULL; uint32_t connPoolSize = 128; uint32_t connPoolCount = 0; void** connPool = __xmalloc(sizeof(void*) * connPoolSize); memset(connPool, 0, sizeof(void*) * connPoolSize); //recieve initial parameters params = readCommand(fd, 5000); if(!params) { fprintf(stderr, "No initialization packet\n"); goto exit; } //make sure the initial packet has all of the required info uint64_t slaveID; const char* command; const char* address; const char* username; const char* password; const char* tableName; int port; int errorChecking; int valueLength; int result = json_unpack(params, "{s:s, s:s, s:i, s:I, s:s, s:s, s:s, s:b, s:i}", "command", &command, "address", &address, "port", &port, "slave-id", &slaveID, "username", &username, "password", &password, "table", &tableName, "error-checking", &errorChecking, "value-length", &valueLength); if(result != 0 || strcmp(command, "init") || port <= 0 || port > 65535) { fprintf(stderr, "Invalid initialization packet recieved\n"); goto exit; } uint64_t numKeys = 0; //loop and execute commands from the master while(1) { nextCommand = readCommand(fd, 15000); if(!nextCommand) { fprintf(stderr, "Invalid next command\n"); goto exit; } const char* command; int result = json_unpack(nextCommand, "{s:s}", "command", &command); if(result == -1) { fprintf(stderr, "Packet missing command field\n"); goto exit; } //parse commands and modify keyRange array if needed struct workerTask task; if(!strcmp(command, "add")) { uint64_t numKeysToAdd; int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToAdd); if(result == -1) { goto exit; } if(errorChecking) { values = __xrealloc(values, sizeof(char*) * (numKeys + numKeysToAdd)); for(uint64_t i = 0; i < numKeysToAdd; i++) { values[numKeys + i] = __xmalloc(valueLength + 1); for(int j = 0; j < valueLength; j++) { values[numKeys + i][j] = (erand48(randContext) * 26) + 'A'; } values[numKeys + i][valueLength] = '\0'; } } task.startingKey = slaveID + numKeys; task.numKeys = numKeysToAdd; task.type = kClientAddKeys; task.values = values; numKeys += task.numKeys; } else if(!strcmp(command, "remove")) { uint64_t numKeysToRemove; int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToRemove); if(result == -1) { goto exit; } if(errorChecking) { uint64_t position = numKeys - numKeysToRemove; for(uint64_t i = 0; i < numKeysToRemove; i++) { free(values[position + i]); } values = __xrealloc(&values, sizeof(char*) * (numKeys - numKeysToRemove)); } if(numKeysToRemove > numKeys) { goto exit; } task.startingKey = slaveID + numKeys - numKeysToRemove; task.numKeys = numKeysToRemove; task.type = kClientRemoveKeys; task.values = NULL; numKeys -= numKeysToRemove; } else if(!strcmp(command, "test")) { json_t* array = json_object_get(nextCommand, "workload"); //right now we only need 1 workload type if(!(json_is_array(array) && json_array_size(array) == kWorkloadTypes)) { goto exit; } for(int i = 0; i < kWorkloadTypes; i++) { task.workloadComposition[i] = json_number_value(json_array_get(array, i)); } int result = json_unpack(nextCommand, "{s:I}", "amount", &task.count); if(result == -1) { goto exit; } task.startingKey = slaveID; task.numKeys = numKeys; task.values = values; task.type = kClientRunWorkload; } else if(!strcmp(command, "quit")) { returnCode = 0; goto exit; } else { fprintf(stderr, "unknown command from client: %s\n", command); goto exit; } int numClients; result = json_unpack(nextCommand, "{s:i, s:F}", "num-clients", &numClients, "throughput", &task.throughput); if(result == -1) { fprintf(stderr, "Packet missing number of clients or throughput value\n"); goto exit; } task.connOpenDelay = 0; //fill out the generic task information task.table = tableName; task.valueSize = valueLength; task.workerID = slaveID; task.hostname = address; task.username = username; task.password = password; task.port = port; //split the request between the clients while(numClients >= connPoolSize) { size_t oldSize = connPoolSize; connPoolSize *= 8; connPool = __xrealloc(connPool, connPoolSize * sizeof(void*)); memset(&connPool[oldSize], 0, sizeof(void*) * oldSize * 7); } if(numClients < connPoolCount) { for(int i = connPoolCount - 1; i >= numClients; i--) { storage_disconnect(connPool[i]); connPool[i] = NULL; } } tasks = __xmalloc(sizeof(struct workerTask) * numClients); splitTasks(&task, tasks, numClients, connPool); //perform the request json_t* requestResponse; performRequest(tasks, numClients, &requestResponse); //save the connections for next time for(int i = 0; i < numClients; i++) { connPool[i] = tasks[i].conn; } connPoolCount = numClients; //send the result back to the master char* serialResponse = json_dumps(requestResponse, JSON_COMPACT); json_decref(requestResponse); size_t len = strlen(serialResponse); if(len > 1048576) { fprintf(stderr, "Response too large (%zd)\n", len); free(serialResponse); goto exit; } char sizeBuf[9]; sprintf(sizeBuf, "%08d", (int)len); sendAll(fd, sizeBuf, 8); if(sendAll(fd, serialResponse, strlen(serialResponse)) == -1) { free(serialResponse); goto exit; } free(serialResponse); free(tasks); tasks = NULL; //free the parsed command json_decref(nextCommand); nextCommand = NULL; } exit: for(uint32_t i = 0; i < connPoolCount; i++) { storage_disconnect(connPool[i]); } free(connPool); free(tasks); json_decref(nextCommand); json_decref(params); if(values) { for(uint64_t i = 0; i < numKeys; i++) { free(values[i]); } free(values); } return returnCode; }
static void run_tests() { json_t *j, *j2; int i1, i2, i3; json_int_t I1; int rv; size_t z; double f; char *s; json_error_t error; /* * Simple, valid json_pack cases */ /* true */ rv = json_unpack(json_true(), "b", &i1); if(rv || !i1) fail("json_unpack boolean failed"); /* false */ rv = json_unpack(json_false(), "b", &i1); if(rv || i1) fail("json_unpack boolean failed"); /* null */ if(json_unpack(json_null(), "n")) fail("json_unpack null failed"); /* integer */ j = json_integer(42); rv = json_unpack(j, "i", &i1); if(rv || i1 != 42) fail("json_unpack integer failed"); json_decref(j); /* json_int_t */ j = json_integer(5555555); rv = json_unpack(j, "I", &I1); if(rv || I1 != 5555555) fail("json_unpack json_int_t failed"); json_decref(j); /* real */ j = json_real(1.7); rv = json_unpack(j, "f", &f); if(rv || f != 1.7) fail("json_unpack real failed"); json_decref(j); /* number */ j = json_integer(12345); rv = json_unpack(j, "F", &f); if(rv || f != 12345.0) fail("json_unpack (real or) integer failed"); json_decref(j); j = json_real(1.7); rv = json_unpack(j, "F", &f); if(rv || f != 1.7) fail("json_unpack real (or integer) failed"); json_decref(j); /* string */ j = json_string("foo"); rv = json_unpack(j, "s", &s); if(rv || strcmp(s, "foo")) fail("json_unpack string failed"); json_decref(j); /* string with length (size_t) */ j = json_string("foo"); rv = json_unpack(j, "s%", &s, &z); if(rv || strcmp(s, "foo") || z != 3) fail("json_unpack string with length (size_t) failed"); json_decref(j); /* empty object */ j = json_object(); if(json_unpack(j, "{}")) fail("json_unpack empty object failed"); json_decref(j); /* empty list */ j = json_array(); if(json_unpack(j, "[]")) fail("json_unpack empty list failed"); json_decref(j); /* non-incref'd object */ j = json_object(); rv = json_unpack(j, "o", &j2); if(rv || j2 != j || j->refcount != 1) fail("json_unpack object failed"); json_decref(j); /* incref'd object */ j = json_object(); rv = json_unpack(j, "O", &j2); if(rv || j2 != j || j->refcount != 2) fail("json_unpack object failed"); json_decref(j); json_decref(j); /* simple object */ j = json_pack("{s:i}", "foo", 42); rv = json_unpack(j, "{s:i}", "foo", &i1); if(rv || i1 != 42) fail("json_unpack simple object failed"); json_decref(j); /* simple array */ j = json_pack("[iii]", 1, 2, 3); rv = json_unpack(j, "[i,i,i]", &i1, &i2, &i3); if(rv || i1 != 1 || i2 != 2 || i3 != 3) fail("json_unpack simple array failed"); json_decref(j); /* object with many items & strict checking */ j = json_pack("{s:i, s:i, s:i}", "a", 1, "b", 2, "c", 3); rv = json_unpack(j, "{s:i, s:i, s:i}", "a", &i1, "b", &i2, "c", &i3); if(rv || i1 != 1 || i2 != 2 || i3 != 3) fail("json_unpack object with many items failed"); json_decref(j); /* * Invalid cases */ j = json_integer(42); if(!json_unpack_ex(j, &error, 0, "z")) fail("json_unpack succeeded with invalid format character"); check_error("Unexpected format character 'z'", "<format>", 1, 1, 1); if(!json_unpack_ex(NULL, &error, 0, "[i]")) fail("json_unpack succeeded with NULL root"); check_error("NULL root value", "<root>", -1, -1, 0); json_decref(j); /* mismatched open/close array/object */ j = json_pack("[]"); if(!json_unpack_ex(j, &error, 0, "[}")) fail("json_unpack failed to catch mismatched ']'"); check_error("Unexpected format character '}'", "<format>", 1, 2, 2); json_decref(j); j = json_pack("{}"); if(!json_unpack_ex(j, &error, 0, "{]")) fail("json_unpack failed to catch mismatched '}'"); check_error("Expected format 's', got ']'", "<format>", 1, 2, 2); json_decref(j); /* missing close array */ j = json_pack("[]"); if(!json_unpack_ex(j, &error, 0, "[")) fail("json_unpack failed to catch missing ']'"); check_error("Unexpected end of format string", "<format>", 1, 2, 2); json_decref(j); /* missing close object */ j = json_pack("{}"); if(!json_unpack_ex(j, &error, 0, "{")) fail("json_unpack failed to catch missing '}'"); check_error("Unexpected end of format string", "<format>", 1, 2, 2); json_decref(j); /* garbage after format string */ j = json_pack("[i]", 42); if(!json_unpack_ex(j, &error, 0, "[i]a", &i1)) fail("json_unpack failed to catch garbage after format string"); check_error("Garbage after format string", "<format>", 1, 4, 4); json_decref(j); j = json_integer(12345); if(!json_unpack_ex(j, &error, 0, "ia", &i1)) fail("json_unpack failed to catch garbage after format string"); check_error("Garbage after format string", "<format>", 1, 2, 2); json_decref(j); /* NULL format string */ j = json_pack("[]"); if(!json_unpack_ex(j, &error, 0, NULL)) fail("json_unpack failed to catch null format string"); check_error("NULL or empty format string", "<format>", -1, -1, 0); json_decref(j); /* NULL string pointer */ j = json_string("foobie"); if(!json_unpack_ex(j, &error, 0, "s", NULL)) fail("json_unpack failed to catch null string pointer"); check_error("NULL string argument", "<args>", 1, 1, 1); json_decref(j); /* invalid types */ j = json_integer(42); j2 = json_string("foo"); if(!json_unpack_ex(j, &error, 0, "s")) fail("json_unpack failed to catch invalid type"); check_error("Expected string, got integer", "<validation>", 1, 1, 1); if(!json_unpack_ex(j, &error, 0, "n")) fail("json_unpack failed to catch invalid type"); check_error("Expected null, got integer", "<validation>", 1, 1, 1); if(!json_unpack_ex(j, &error, 0, "b")) fail("json_unpack failed to catch invalid type"); check_error("Expected true or false, got integer", "<validation>", 1, 1, 1); if(!json_unpack_ex(j2, &error, 0, "i")) fail("json_unpack failed to catch invalid type"); check_error("Expected integer, got string", "<validation>", 1, 1, 1); if(!json_unpack_ex(j2, &error, 0, "I")) fail("json_unpack failed to catch invalid type"); check_error("Expected integer, got string", "<validation>", 1, 1, 1); if(!json_unpack_ex(j, &error, 0, "f")) fail("json_unpack failed to catch invalid type"); check_error("Expected real, got integer", "<validation>", 1, 1, 1); if(!json_unpack_ex(j2, &error, 0, "F")) fail("json_unpack failed to catch invalid type"); check_error("Expected real or integer, got string", "<validation>", 1, 1, 1); if(!json_unpack_ex(j, &error, 0, "[i]")) fail("json_unpack failed to catch invalid type"); check_error("Expected array, got integer", "<validation>", 1, 1, 1); if(!json_unpack_ex(j, &error, 0, "{si}", "foo")) fail("json_unpack failed to catch invalid type"); check_error("Expected object, got integer", "<validation>", 1, 1, 1); json_decref(j); json_decref(j2); /* Array index out of range */ j = json_pack("[i]", 1); if(!json_unpack_ex(j, &error, 0, "[ii]", &i1, &i2)) fail("json_unpack failed to catch index out of array bounds"); check_error("Array index 1 out of range", "<validation>", 1, 3, 3); json_decref(j); /* NULL object key */ j = json_pack("{si}", "foo", 42); if(!json_unpack_ex(j, &error, 0, "{si}", NULL, &i1)) fail("json_unpack failed to catch null string pointer"); check_error("NULL object key", "<args>", 1, 2, 2); json_decref(j); /* Object key not found */ j = json_pack("{si}", "foo", 42); if(!json_unpack_ex(j, &error, 0, "{si}", "baz", &i1)) fail("json_unpack failed to catch null string pointer"); check_error("Object item not found: baz", "<validation>", 1, 3, 3); json_decref(j); /* * Strict validation */ j = json_pack("[iii]", 1, 2, 3); rv = json_unpack(j, "[iii!]", &i1, &i2, &i3); if(rv || i1 != 1 || i2 != 2 || i3 != 3) fail("json_unpack array with strict validation failed"); json_decref(j); j = json_pack("[iii]", 1, 2, 3); if(!json_unpack_ex(j, &error, 0, "[ii!]", &i1, &i2)) fail("json_unpack array with strict validation failed"); check_error("1 array item(s) left unpacked", "<validation>", 1, 5, 5); json_decref(j); /* Like above, but with JSON_STRICT instead of '!' format */ j = json_pack("[iii]", 1, 2, 3); if(!json_unpack_ex(j, &error, JSON_STRICT, "[ii]", &i1, &i2)) fail("json_unpack array with strict validation failed"); check_error("1 array item(s) left unpacked", "<validation>", 1, 4, 4); json_decref(j); j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42); rv = json_unpack(j, "{sssi!}", "foo", &s, "baz", &i1); if(rv || strcmp(s, "bar") != 0 || i1 != 42) fail("json_unpack object with strict validation failed"); json_decref(j); /* Unpack the same item twice */ j = json_pack("{s:s, s:i, s:b}", "foo", "bar", "baz", 42, "quux", 1); if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s)) fail("json_unpack object with strict validation failed"); { const char *possible_errors[] = { "2 object item(s) left unpacked: baz, quux", "2 object item(s) left unpacked: quux, baz" }; check_errors(possible_errors, 2, "<validation>", 1, 10, 10); } json_decref(j); j = json_pack("[i,{s:i,s:n},[i,i]]", 1, "foo", 2, "bar", 3, 4); if(json_unpack_ex(j, NULL, JSON_STRICT | JSON_VALIDATE_ONLY, "[i{sisn}[ii]]", "foo", "bar")) fail("json_unpack complex value with strict validation failed"); json_decref(j); /* ! and * must be last */ j = json_pack("[ii]", 1, 2); if(!json_unpack_ex(j, &error, 0, "[i!i]", &i1, &i2)) fail("json_unpack failed to catch ! in the middle of an array"); check_error("Expected ']' after '!', got 'i'", "<format>", 1, 4, 4); if(!json_unpack_ex(j, &error, 0, "[i*i]", &i1, &i2)) fail("json_unpack failed to catch * in the middle of an array"); check_error("Expected ']' after '*', got 'i'", "<format>", 1, 4, 4); json_decref(j); j = json_pack("{sssi}", "foo", "bar", "baz", 42); if(!json_unpack_ex(j, &error, 0, "{ss!si}", "foo", &s, "baz", &i1)) fail("json_unpack failed to catch ! in the middle of an object"); check_error("Expected '}' after '!', got 's'", "<format>", 1, 5, 5); if(!json_unpack_ex(j, &error, 0, "{ss*si}", "foo", &s, "baz", &i1)) fail("json_unpack failed to catch ! in the middle of an object"); check_error("Expected '}' after '*', got 's'", "<format>", 1, 5, 5); json_decref(j); /* Error in nested object */ j = json_pack("{s{snsn}}", "foo", "bar", "baz"); if(!json_unpack_ex(j, &error, 0, "{s{sn!}}", "foo", "bar")) fail("json_unpack nested object with strict validation failed"); check_error("1 object item(s) left unpacked: baz", "<validation>", 1, 7, 7); json_decref(j); /* Error in nested array */ j = json_pack("[[ii]]", 1, 2); if(!json_unpack_ex(j, &error, 0, "[[i!]]", &i1)) fail("json_unpack nested array with strict validation failed"); check_error("1 array item(s) left unpacked", "<validation>", 1, 5, 5); json_decref(j); /* Optional values */ j = json_object(); i1 = 0; if(json_unpack(j, "{s?i}", "foo", &i1)) fail("json_unpack failed for optional key"); if(i1 != 0) fail("json_unpack unpacked an optional key"); json_decref(j); i1 = 0; j = json_pack("{si}", "foo", 42); if(json_unpack(j, "{s?i}", "foo", &i1)) fail("json_unpack failed for an optional value"); if(i1 != 42) fail("json_unpack failed to unpack an optional value"); json_decref(j); j = json_object(); i1 = i2 = i3 = 0; if(json_unpack(j, "{s?[ii]s?{s{si}}}", "foo", &i1, &i2, "bar", "baz", "quux", &i3)) fail("json_unpack failed for complex optional values"); if(i1 != 0 || i2 != 0 || i3 != 0) fail("json_unpack unexpectedly unpacked something"); json_decref(j); j = json_pack("{s{si}}", "foo", "bar", 42); if(json_unpack(j, "{s?{s?i}}", "foo", "bar", &i1)) fail("json_unpack failed for complex optional values"); if(i1 != 42) fail("json_unpack failed to unpack"); json_decref(j); /* Combine ? and ! */ j = json_pack("{si}", "foo", 42); i1 = i2 = 0; if(json_unpack(j, "{sis?i!}", "foo", &i1, "bar", &i2)) fail("json_unpack failed for optional values with strict mode"); if(i1 != 42) fail("json_unpack failed to unpack"); if(i2 != 0) fail("json_unpack failed to unpack"); json_decref(j); /* But don't compensate a missing key with an optional one. */ j = json_pack("{sisi}", "foo", 42, "baz", 43); i1 = i2 = i3 = 0; if(!json_unpack_ex(j, &error, 0, "{sis?i!}", "foo", &i1, "bar", &i2)) fail("json_unpack failed for optional values with strict mode and compensation"); check_error("1 object item(s) left unpacked: baz", "<validation>", 1, 8, 8); json_decref(j); }
struct watchman_trigger_command *w_build_trigger_from_def( w_root_t *root, json_t *trig, char **errmsg) { struct watchman_trigger_command *cmd; json_t *ele, *query, *relative_root; json_int_t jint; const char *name = NULL; cmd = calloc(1, sizeof(*cmd)); if (!cmd) { *errmsg = strdup("no memory"); return NULL; } cmd->definition = trig; json_incref(cmd->definition); query = json_pack("{s:O}", "expression", json_object_get(cmd->definition, "expression")); relative_root = json_object_get(cmd->definition, "relative_root"); if (relative_root) { json_object_set_nocheck(query, "relative_root", relative_root); } cmd->query = w_query_parse(root, query, errmsg); json_decref(query); if (!cmd->query) { w_trigger_command_free(cmd); return NULL; } json_unpack(trig, "{s:u}", "name", &name); if (!name) { *errmsg = strdup("invalid or missing name"); w_trigger_command_free(cmd); return NULL; } cmd->triggername = w_string_new_typed(name, W_STRING_UNICODE); cmd->command = json_object_get(trig, "command"); if (cmd->command) { json_incref(cmd->command); } if (!cmd->command || !json_is_array(cmd->command) || !json_array_size(cmd->command)) { *errmsg = strdup("invalid command array"); w_trigger_command_free(cmd); return NULL; } json_unpack(trig, "{s:b}", "append_files", &cmd->append_files); ele = json_object_get(trig, "stdin"); if (!ele) { cmd->stdin_style = input_dev_null; } else if (json_is_array(ele)) { cmd->stdin_style = input_json; if (!parse_field_list(ele, &cmd->field_list, errmsg)) { w_trigger_command_free(cmd); return NULL; } } else if (json_is_string(ele)) { const char *str = json_string_value(ele); if (!strcmp(str, "/dev/null")) { cmd->stdin_style = input_dev_null; } else if (!strcmp(str, "NAME_PER_LINE")) { cmd->stdin_style = input_name_list; } else { ignore_result(asprintf(errmsg, "invalid stdin value %s", str)); w_trigger_command_free(cmd); return NULL; } } else { *errmsg = strdup("invalid value for stdin"); w_trigger_command_free(cmd); return NULL; } jint = 0; // unlimited unless specified json_unpack(trig, "{s:I}", "max_files_stdin", &jint); if (jint < 0) { *errmsg = strdup("max_files_stdin must be >= 0"); w_trigger_command_free(cmd); return NULL; } cmd->max_files_stdin = (uint32_t)jint; json_unpack(trig, "{s:s}", "stdout", &cmd->stdout_name); json_unpack(trig, "{s:s}", "stderr", &cmd->stderr_name); if (!parse_redirection(&cmd->stdout_name, &cmd->stdout_flags, "stdout", errmsg)) { w_trigger_command_free(cmd); return NULL; } if (!parse_redirection(&cmd->stderr_name, &cmd->stderr_flags, "stderr", errmsg)) { w_trigger_command_free(cmd); return NULL; } // Copy current environment cmd->envht = w_envp_make_ht(); // Set some standard vars w_envp_set(cmd->envht, "WATCHMAN_ROOT", root->root_path); w_envp_set_cstring(cmd->envht, "WATCHMAN_SOCK", get_sock_name()); w_envp_set(cmd->envht, "WATCHMAN_TRIGGER", cmd->triggername); return cmd; }