Example #1
0
void owl_perlconfig_edit_callback(owl_editwin *e, bool success)
{
  SV *cb = owl_editwin_get_cbdata(e);
  SV *text;
  dSP;

  if(cb == NULL) {
    owl_function_error("Perl callback is NULL!");
    return;
  }
  text = owl_new_sv(owl_editwin_get_text(e));

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);
  XPUSHs(sv_2mortal(text));
  XPUSHs(sv_2mortal(newSViv(success)));
  PUTBACK;
  
  call_sv(cb, G_DISCARD|G_EVAL);

  if(SvTRUE(ERRSV)) {
    owl_function_error("%s", SvPV_nolen(ERRSV));
  }

  FREETMPS;
  LEAVE;
}
Example #2
0
/* Calls a method on a perl object representing a message.
   If the return value is non-null, the caller must free it.
 */
CALLER_OWN char *owl_perlconfig_message_call_method(const owl_message *m, const char *method, int argc, const char **argv)
{
  dSP;
  unsigned int count, i;
  SV *msgref, *srv;
  char *out;

  msgref = owl_perlconfig_message2hashref(m);

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);
  XPUSHs(sv_2mortal(msgref));
  for(i=0;i<argc;i++) {
    XPUSHs(sv_2mortal(owl_new_sv(argv[i])));
  }
  PUTBACK;

  count = call_method(method, G_SCALAR|G_EVAL);

  SPAGAIN;

  if(count != 1) {
    fprintf(stderr, "perl returned wrong count %u\n", count);
    abort();
  }

  if (SvTRUE(ERRSV)) {
    owl_function_error("Error: '%s'", SvPV_nolen(ERRSV));
    /* and clear the error */
    sv_setsv (ERRSV, &PL_sv_undef);
  }

  srv = POPs;

  if (srv) {
    out = g_strdup(SvPV_nolen(srv));
  } else {
    out = NULL;
  }

  PUTBACK;
  FREETMPS;
  LEAVE;

  return out;
}
Example #3
0
void owl_perlconfig_new_command(const char *name)
{
  dSP;

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);
  XPUSHs(sv_2mortal(owl_new_sv(name)));
  PUTBACK;

  call_pv("BarnOwl::Hooks::_new_command", G_VOID|G_EVAL);

  SPAGAIN;

  if(SvTRUE(ERRSV)) {
    owl_function_error("%s", SvPV_nolen(ERRSV));
  }

  FREETMPS;
  LEAVE;
}
Example #4
0
/* caller must free the result */
CALLER_OWN char *owl_perlconfig_perlcmd(const owl_cmd *cmd, int argc, const char *const *argv)
{
  int i, count;
  char * ret = NULL;
  SV *rv;
  dSP;

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);
  for(i=0;i<argc;i++) {
    XPUSHs(sv_2mortal(owl_new_sv(argv[i])));
  }
  PUTBACK;

  count = call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL);

  SPAGAIN;

  if(SvTRUE(ERRSV)) {
    owl_function_error("%s", SvPV_nolen(ERRSV));
    (void)POPs;
  } else {
    if(count != 1)
      croak("Perl command %s returned more than one value!", cmd->name);
    rv = POPs;
    if(SvTRUE(rv)) {
      ret = g_strdup(SvPV_nolen(rv));
    }
  }

  FREETMPS;
  LEAVE;

  return ret;
}
Example #5
0
CALLER_OWN SV *owl_perlconfig_message2hashref(const owl_message *m)
{
  HV *h, *stash;
  SV *hr;
  const char *type;
  char *ptr, *utype, *blessas;
  const char *f;
  int i;
  const owl_pair *pair;
  const owl_filter *wrap;

  if (!m) return &PL_sv_undef;
  wrap = owl_global_get_filter(&g, "wordwrap");
  if(!wrap) {
      owl_function_error("wrap filter is not defined");
      return &PL_sv_undef;
  }

  h = newHV();

#define MSG2H(h,field) (void)hv_store(h, #field, strlen(#field),        \
                                      owl_new_sv(owl_message_get_##field(m)), 0)

  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
    /* Handle zephyr-specific fields... */
    AV *av_zfields = newAV();
    if (owl_message_get_notice(m)) {
      for (f = owl_zephyr_first_raw_field(owl_message_get_notice(m)); f != NULL;
           f = owl_zephyr_next_raw_field(owl_message_get_notice(m), f)) {
        ptr = owl_zephyr_field_as_utf8(owl_message_get_notice(m), f);
        av_push(av_zfields, owl_new_sv(ptr));
        g_free(ptr);
      }
      (void)hv_store(h, "auth", strlen("auth"),
                     owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))), 0);
    } else {
      /* Incoming zephyrs without a ZNotice_t are pseudo-logins. To appease
       * existing styles, put in bogus 'auth' and 'fields' keys. */
      (void)hv_store(h, "auth", strlen("auth"), owl_new_sv("NO"), 0);
    }
    (void)hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);
  }

  for (i = 0; i < m->attributes->len; i++) {
    pair = m->attributes->pdata[i];
    (void)hv_store(h, owl_pair_get_key(pair), strlen(owl_pair_get_key(pair)),
                   owl_new_sv(owl_pair_get_value(pair)),0);
  }
  
  MSG2H(h, type);
  MSG2H(h, direction);
  MSG2H(h, class);
  MSG2H(h, instance);
  MSG2H(h, sender);
  MSG2H(h, realm);
  MSG2H(h, recipient);
  MSG2H(h, opcode);
  MSG2H(h, hostname);
  MSG2H(h, body);
  MSG2H(h, login);
  MSG2H(h, zsig);
  MSG2H(h, zwriteline);
  if (owl_message_get_header(m)) {
    MSG2H(h, header); 
  }
  (void)hv_store(h, "time", strlen("time"), owl_new_sv(owl_message_get_timestr(m)),0);
  (void)hv_store(h, "unix_time", strlen("unix_time"), newSViv(m->time), 0);
  (void)hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
  (void)hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
  (void)hv_store(h, "private", strlen("private"), newSViv(owl_message_is_private(m)),0);
  (void)hv_store(h, "should_wordwrap",
                 strlen("should_wordwrap"), newSViv(
                                                    owl_filter_message_match(wrap, m)),0);

  type = owl_message_get_type(m);
  if(!type || !*type) type = "generic";
  utype = g_strdup(type);
  utype[0] = toupper(type[0]);
  blessas = g_strdup_printf("BarnOwl::Message::%s", utype);

  hr = newRV_noinc((SV*)h);
  stash =  gv_stashpv(blessas,0);
  if(!stash) {
    owl_function_error("No such class: %s for message type %s", blessas, owl_message_get_type(m));
    stash = gv_stashpv("BarnOwl::Message", 1);
  }
  hr = sv_bless(hr,stash);
  g_free(utype);
  g_free(blessas);
  return hr;
}
Example #6
0
/* caller must free result, if not NULL */
CALLER_OWN char *owl_perlconfig_initperl(const char *file, int *Pargc, char ***Pargv, char ***Penv)
{
  int ret;
  PerlInterpreter *p;
  char *err;
  const char *args[4] = {"", "-e", "0;", NULL};
  AV *inc;
  char *path;

  /* create and initialize interpreter */
  PERL_SYS_INIT3(Pargc, Pargv, Penv);
  p=perl_alloc();
  owl_global_set_perlinterp(&g, p);
  perl_construct(p);

  PL_exit_flags |= PERL_EXIT_DESTRUCT_END;

  owl_global_set_no_have_config(&g);

  ret=perl_parse(p, owl_perl_xs_init, 2, (char **)args, NULL);
  if (ret || SvTRUE(ERRSV)) {
    err=g_strdup(SvPV_nolen(ERRSV));
    sv_setsv(ERRSV, &PL_sv_undef);     /* and clear the error */
    return(err);
  }

  ret=perl_run(p);
  if (ret || SvTRUE(ERRSV)) {
    err=g_strdup(SvPV_nolen(ERRSV));
    sv_setsv(ERRSV, &PL_sv_undef);     /* and clear the error */
    return(err);
  }

  owl_global_set_have_config(&g);

  /* create legacy variables */
  get_sv("BarnOwl::id", TRUE);
  get_sv("BarnOwl::class", TRUE);
  get_sv("BarnOwl::instance", TRUE);
  get_sv("BarnOwl::recipient", TRUE);
  get_sv("BarnOwl::sender", TRUE);
  get_sv("BarnOwl::realm", TRUE);
  get_sv("BarnOwl::opcode", TRUE);
  get_sv("BarnOwl::zsig", TRUE);
  get_sv("BarnOwl::msg", TRUE);
  get_sv("BarnOwl::time", TRUE);
  get_sv("BarnOwl::host", TRUE);
  get_av("BarnOwl::fields", TRUE);

  if(file) {
    SV * cfg = get_sv("BarnOwl::configfile", TRUE);
    sv_setpv(cfg, file);
  }

  sv_setpv(get_sv("BarnOwl::VERSION", TRUE), OWL_VERSION_STRING);

  /* Add the system lib path to @INC */
  inc = get_av("INC", 0);
  path = g_build_filename(owl_get_datadir(), "lib", NULL);
  av_unshift(inc, 1);
  av_store(inc, 0, owl_new_sv(path));
  g_free(path);

  eval_pv("use BarnOwl;", FALSE);

  if (SvTRUE(ERRSV)) {
    err=g_strdup(SvPV_nolen(ERRSV));
    sv_setsv (ERRSV, &PL_sv_undef);     /* and clear the error */
    return(err);
  }

  /* check if we have the formatting function */
  if (owl_perlconfig_is_function("BarnOwl::format_msg")) {
    owl_global_set_config_format(&g, 1);
  }

  return(NULL);
}
Example #7
0
SV *owl_filter_to_sv(const owl_filter *f)
{
  return owl_new_sv(owl_filter_get_name(f));
}
Example #8
0
SV *owl_perlconfig_message2hashref(const owl_message *m)
{
  HV *h, *stash;
  SV *hr;
  const char *type;
  char *ptr, *utype, *blessas;
  int i, j;
  const owl_pair *pair;
  const owl_filter *wrap;

  if (!m) return &PL_sv_undef;
  wrap = owl_global_get_filter(&g, "wordwrap");
  if(!wrap) {
      owl_function_error("wrap filter is not defined");
      return &PL_sv_undef;
  }

  h = newHV();

#define MSG2H(h,field) (void)hv_store(h, #field, strlen(#field),        \
                                      owl_new_sv(owl_message_get_##field(m)), 0)

  if (owl_message_is_type_zephyr(m)
      && owl_message_is_direction_in(m)) {
    /* Handle zephyr-specific fields... */
    AV *av_zfields;

    av_zfields = newAV();
    j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
    for (i=0; i<j; i++) {
      ptr=owl_zephyr_get_field_as_utf8(owl_message_get_notice(m), i+1);
      av_push(av_zfields, owl_new_sv(ptr));
      owl_free(ptr);
    }
    (void)hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);

    (void)hv_store(h, "auth", strlen("auth"), 
                   owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))),0);
  }

  j=owl_list_get_size(&(m->attributes));
  for(i=0; i<j; i++) {
    pair=owl_list_get_element(&(m->attributes), i);
    (void)hv_store(h, owl_pair_get_key(pair), strlen(owl_pair_get_key(pair)),
                   owl_new_sv(owl_pair_get_value(pair)),0);
  }
  
  MSG2H(h, type);
  MSG2H(h, direction);
  MSG2H(h, class);
  MSG2H(h, instance);
  MSG2H(h, sender);
  MSG2H(h, realm);
  MSG2H(h, recipient);
  MSG2H(h, opcode);
  MSG2H(h, hostname);
  MSG2H(h, body);
  MSG2H(h, login);
  MSG2H(h, zsig);
  MSG2H(h, zwriteline);
  if (owl_message_get_header(m)) {
    MSG2H(h, header); 
  }
  (void)hv_store(h, "time", strlen("time"), owl_new_sv(owl_message_get_timestr(m)),0);
  (void)hv_store(h, "unix_time", strlen("unix_time"), newSViv(m->time), 0);
  (void)hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
  (void)hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
  (void)hv_store(h, "private", strlen("private"), newSViv(owl_message_is_private(m)),0);
  (void)hv_store(h, "should_wordwrap",
                 strlen("should_wordwrap"), newSViv(
                                                    owl_filter_message_match(wrap, m)),0);

  type = owl_message_get_type(m);
  if(!type || !*type) type = "generic";
  utype = owl_strdup(type);
  utype[0] = toupper(type[0]);
  blessas = owl_sprintf("BarnOwl::Message::%s", utype);

  hr = newRV_noinc((SV*)h);
  stash =  gv_stashpv(blessas,0);
  if(!stash) {
    owl_function_error("No such class: %s for message type %s", blessas, owl_message_get_type(m));
    stash = gv_stashpv("BarnOwl::Message", 1);
  }
  hr = sv_bless(hr,stash);
  owl_free(utype);
  owl_free(blessas);
  return hr;
}