Exemple #1
0
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;
}
Exemple #2
0
/* 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));
}
Exemple #4
0
/* 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);
}
Exemple #5
0
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);
}
Exemple #6
0
/*
 * 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()
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
    }
}
Exemple #10
0
	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;
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
bool locationClass::parse(json_t* input) {
	if (json_unpack(input, "{s:F,s:F}", "latitude", &_lat, "longitude", &_lon)) {
		return false;
	}
	return this->isValid();
}
Exemple #15
0
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);
  }
}
Exemple #16
0
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;
}
Exemple #18
0
Fichier : slave.c Projet : rv1/esb
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;
}
Exemple #19
0
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);
}
Exemple #20
0
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;
}