Exemple #1
0
int next_request(struct remote *rx)
{
  char *ptr;

  rx->r_match = NULL;

  if(rx->r_index >= rx->r_count){
    return 1;
  }

  ptr = get_string_parse_katcl(rx->r_vector[rx->r_index], 0);
  if(ptr == NULL){
    return -1;
  }
  if(ptr[0] != KATCP_REQUEST){
    return -1;
  }

  if(append_parse_katcl(rx->r_line, rx->r_vector[rx->r_index]) < 0){
    return -1;
  }

  rx->r_match = ptr + 1;
  rx->r_index++;

  return 0;
}
Exemple #2
0
int relay_katcl(struct katcl_line *lx, struct katcl_line *ly)
{
  if(lx->l_ready == NULL){
    return -1;
  }

  return append_parse_katcl(ly, lx->l_ready);
}
int perform_sensor_update_katcp(struct katcp_dispatch *d, void *data)
{
  struct katcp_shared *s;
  unsigned int i, j, count;
  struct katcp_flat *fx;
  struct katcp_group *gx;
  struct katcl_parse *px;

  s = d->d_shared;
  if(s == NULL){
    return -1;
  }

  if(s->s_changes <= 0){
    log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "logic problem: scheduled device update, but nothing requires updating");
    return -1;
  }

  px = create_referenced_parse_katcl();
  if(px == NULL){
    return -1;
  }

  add_string_parse_katcl(px, KATCP_FLAG_FIRST | KATCP_FLAG_STRING, KATCP_DEVICE_CHANGED_INFORM);
  add_string_parse_katcl(px, KATCP_FLAG_LAST | KATCP_FLAG_STRING, "sensor-list");

  count = 0;

  for(j = 0; j < s->s_members; j++){
    gx = s->s_groups[j];
    for(i = 0; i < gx->g_count; i++){
      fx = is_ready_flat_katcp(d, gx->g_flats[i]);
      if(fx){
        if((fx->f_stale & KATCP_STALE_MASK_SENSOR) == KATCP_STALE_SENSOR_STALE){
          fx->f_stale = KATCP_STALE_SENSOR_NAIVE;

          if((fx->f_flags & KATCP_FLAT_TOCLIENT) && (fx->f_flags & KATCP_FLAT_SEESKATCP)){
            /* TODO: shouldn't we use the fancy queue infrastructure ? */
            append_parse_katcl(fx->f_line, px);
            count++;
          }
        }
      }
    }
  }

  log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "notified %u clients of %u sensor %s", count, s->s_changes, (s->s_changes == 1) ? "change" : "changes");

  destroy_parse_katcl(px);

  s->s_changes = 0;

  return 0;
}
Exemple #4
0
void dump_katcl(struct katcl_line *l, FILE *fp)
{
  fprintf(fp, "input: fd=%d\n", l->l_fd);

  dump_parse_katcl(l->l_ready, "ready", fp);
  dump_parse_katcl(l->l_next, "next", fp);

  fflush(fp);

  append_parse_katcl(l, l->l_ready);
  write_katcl(l);
}
Exemple #5
0
int main()
{
  struct katcl_line *l;
  struct katcl_parse *p;
  int count, seed, i, k, fds[2], result, al, bl;
  char alpha[MAX_ARG_LEN], beta[MAX_ARG_LEN];
  pid_t pid;

  seed = getpid();
  printf("line test: seed is %d\n", seed);
  srand(seed);

  if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0){
    fprintf(stderr, "line: unable to create socketpair\n");
    return 1;
  }

  pid = fork();
  if(pid < 0){
    fprintf(stderr, "line: unable to fork\n");
    return 1;
  }

  if(pid == 0){
    close(fds[0]);
    echobuffer(fds[1]);
    return 0;
  }

  close(fds[1]);

  l = create_katcl(fds[0]);
  if(l == NULL){
    fprintf(stderr, "main: unable to create katcl\n");
    return 1;
  }

  for(i = 0; i < TEST_RUNS; i++){

#ifdef DEBUG
    fprintf(stderr, "line test: iteration %d\n", i);
#endif

    p = create_referenced_parse_katcl();
    if(p == NULL){
      fprintf(stderr, "unable to create parse instance %d\n", i);
      return 1;
    }

#ifdef DEBUG
    fprintf(stderr, "test: ref before submission %d\n", p->p_refs);
#endif

    fill_random_test(p);
    dump_parse_katcl(p, "random", stderr);

    if(append_parse_katcl(l, p) < 0){ 
      fprintf(stderr, "unable to add parse %d\n", i);
      return 1;
    }

#ifdef DEBUG
    fprintf(stderr, "test: ref after submission %d\n", p->p_refs);
#endif

    while((result = write_katcl(l)) == 0);

#ifdef DEBUG
    fprintf(stderr, "test: ref after write %d\n", p->p_refs);
#endif

    if(result < 0){
      fprintf(stderr, "unable to write data\n");
      return 1;
    }

    do{
      result = read_katcl(l);
      if(result){
        fprintf(stderr, "read result is %d\n", result);
        return 1;
      }
    } while(have_katcl(l) == 0);

    count = arg_count_katcl(l);

    for(k = 0; k < count; k++){
      al = arg_buffer_katcl(l, k, alpha, MAX_ARG_LEN);
      bl = get_buffer_parse_katcl(p, k, beta, MAX_ARG_LEN);

      if((bl < 0) || (al < 0)){
        fprintf(stderr, "al=%d, bl=%d\n", al, bl);
        return 1;
      }

      if(al != bl){
        fprintf(stderr, "al=%d != bl=%d\n", al, bl);
        return 1;
      }

      if(memcmp(alpha, beta, al)){
        fprintf(stderr, "mismatch: round=%d, arg=%d\n", i, k); 
        return 1;
      }
    }

    fprintf(stderr, "parsed a line with %d words\n", count);

    destroy_parse_katcl(p);

  }

  destroy_katcl(l, 1);

  printf("line test: ok\n");

  return 0;
}
Exemple #6
0
int main(int argc, char **argv)
{
#define BUFFER 64
  char buffer[BUFFER];
  char *level, *app, *server, *output;
  int run, fd, i, j, c, verbose, attempts, detach, result, truncate, flags;
  struct katcl_parse *p;
  struct katcl_line *ls, *lo;
  struct sigaction sa;
  time_t now;
  struct tm *local;

  i = j = 1;
  app = argv[0];

  verbose = 0;
  attempts = 2;
  detach = 0;
  truncate = 0;

  server = getenv("KATCP_SERVER");
  if(server == NULL){
    server = "localhost";
  }

  output = NULL;
  level = NULL;

  flags = 0; /* placate -Wall */

  while (i < argc) {
    if (argv[i][0] == '-') {
      c = argv[i][j];
      switch (c) {

        case 'h' :
          usage(app);
          return EX_OK;

        case 'v' : 
          verbose++;
          j++;
          break;

        case 'd' : 
          detach = 1;
          j++;
          break;

        case 'f' : 
          detach = 0;
          j++;
          break;

        case 't' : 
          truncate = 1;
          j++;
          break;

        case 'q' : 
          verbose = 0;
          j++;
          break;

        case 'l' :
        case 'o' :
        case 'a' :
        case 's' :

          j++;
          if (argv[i][j] == '\0') {
            j = 0;
            i++;
          }
          if (i >= argc) {
            fprintf(stderr, "%s: usage: argument needs a parameter\n", app);
            return EX_USAGE;
          }

          switch(c){
            case 'l' :
              level = argv[i] + j;
              break;
            case 'o' :
              output = argv[i] + j;
              break;
            case 'a' : 
              attempts = atoi(argv[i] + j);
              break;
            case 's' : 
              server = argv[i] + j;
              break;
          }

          i++;
          j = 1;
          break;

        case '-' :
          j++;
          break;
        case '\0':
          j = 1;
          i++;
          break;
        default:
          fprintf(stderr, "%s: usage: unknown option -%c\n", app, argv[i][j]);
          return EX_USAGE;
      }
    } else {
      if(output){
        fprintf(stderr, "%s: usage: unexpected extra argument %s (can only save to one file)\n", app, argv[i]);
        return EX_USAGE;
      } 
      output = argv[i];
      i++;
    }
  }

  if(detach){
    if(fork_parent() < 0){
      fprintf(stderr, "%s: unable to detach process\n", app);
      return EX_OSERR;
    }
  }

  sa.sa_handler = handle_signal;
#if 0
  sa.sa_flags = SA_RESTART;
#endif
  sa.sa_flags = 0;
  sigemptyset(&(sa.sa_mask));

  sigaction(SIGHUP, &sa, NULL);
  sigaction(SIGUSR1, &sa, NULL);
  sigaction(SIGUSR2, &sa, NULL);

  if(server == NULL){
    server = "localhost:7147";
  }

  if(level){
    log_changed = 1;
    log_level = log_to_code_katcl(level);
    if(log_level < 0){
      fprintf(stderr, "%s: usage: invalid initial log priority %s\n", app, level);
      return EX_USAGE;
    } 
  }

  if(output == NULL){
    if(detach == 1){
      fprintf(stderr, "%s: usage: need a filename as target\n", app);
      return EX_USAGE;
    }
    fd = STDOUT_FILENO;
  } else {
    flags = O_CREAT | O_WRONLY;
    if(truncate == 0){
      flags |= O_APPEND;
    }
    fd = open(output, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
    if(fd < 0){
      fprintf(stderr, "%s: unable to open file %s: %s\n", app, output, strerror(errno));
      return EX_OSERR;
    }
  }

  lo = create_katcl(fd);
  if(lo == NULL){
    fprintf(stderr, "%s: unable to allocate log state\n", app);
    return EX_OSERR;
  }


  /**********************/

  while((attempts-- > 0) && ((fd = net_connect(server, 0, 0)) < 0)){
    sleep(1);
  }

  if(attempts <= 0){
    sync_message_katcl(lo, KATCP_LEVEL_FATAL, NAME, "unable to connect to %s", server);
    return EX_UNAVAILABLE;
  }

  ls = create_katcl(fd);
  if(ls == NULL){
    sync_message_katcl(lo, KATCP_LEVEL_FATAL, NAME, "unable to allocate parser state");
    return EX_OSERR;
  }

  if(detach){
    fclose(stderr);
  }

  time(&now);
  local = localtime(&now);
  strftime(buffer, BUFFER - 1, "%Y-%m-%dT%H:%M:%S", local);

  sync_message_katcl(lo, KATCP_LEVEL_INFO, NAME, "monitor start for %s at %s", server, buffer);

  for(run = 1; run > 0;){

    if(log_reload > 0){
      if(output){
        fd = open(output, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
        if(fd >= 0){
          exchange_katcl(lo, fd);
        }
      }

      log_reload = 0;
    }
 
    /* WARNING: will only run after the next message - may have to interrupt syscall to get past this */
    if(log_changed > 0){

      level = log_to_string_katcl(log_level);
      if(level){

        p = create_parse_katcl();
        if(p){

          add_string_parse_katcl(p, KATCP_FLAG_STRING | KATCP_FLAG_FIRST, "?log-level");
          add_string_parse_katcl(p, KATCP_FLAG_STRING | KATCP_FLAG_LAST, level);

          append_parse_katcl(lo, p);

          /* dodgy refcount dealings: p is created with refcount = 0, so can only do write at end, otherwise may end up being deallocated */

          append_parse_katcl(ls, p);
          write_katcl(ls);

        }
      } else {
        sync_message_katcl(lo, KATCP_LEVEL_ERROR, NAME, "invalid log priority number %d", level);
      }

      log_changed = 0;
    }

    result = read_katcl(ls);
    if(result < 0){
      sync_message_katcl(lo, KATCP_LEVEL_FATAL, NAME, "read from network failed: %s", strerror(errno));
      return EX_OSERR;
    }

    if(result == 1){
      run = 0;
    }

    while(have_katcl(ls)){
      p = ready_katcl(ls);
      if(p){
        append_parse_katcl(lo, p);
      }
    }

    write_katcl(lo);
  }

  return EX_OK;
#undef BUFFER
}