示例#1
0
文件: zephyr.c 项目: arlynap/barnowl
int owl_zephyr_loadsubs_helper(ZSubscription_t subs[], int count)
{
  int ret = 0;
  if (owl_global_is_havezephyr(&g)) {
    int i;
    /* sub without defaults */
    if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
      owl_function_error("Error subscribing to zephyr notifications.");
      ret=-2;
    }

    /* free stuff */
    for (i=0; i<count; i++) {
      owl_free(subs[i].zsub_class);
      owl_free(subs[i].zsub_classinst);
      owl_free(subs[i].zsub_recipient);
    }

    owl_free(subs);
  } else {
    owl_sub_list *s = owl_malloc(sizeof(owl_sub_list));
    s->subs = subs;
    s->nsubs = count;
    deferred_subs = g_list_append(deferred_subs, s);
  }

  return ret;
}
示例#2
0
owl_variable * owl_variable_newvar(char *name, char *summary, char * description) {
  owl_variable * var = (owl_variable*)owl_malloc(sizeof(owl_variable));
  memset(var, 0, sizeof(owl_variable));
  var->name = owl_strdup(name);
  var->summary = owl_strdup(summary);
  var->description = owl_strdup(description);
  return var;
}
示例#3
0
文件: zephyr.c 项目: arlynap/barnowl
int owl_zephyr_loadloginsubs(char *filename)
{
#ifdef HAVE_LIBZEPHYR
  FILE *file;
  ZSubscription_t *subs;
  int numSubs = 100;
  char subsfile[1024], buffer[1024];
  int count, ret;
  struct stat statbuff;

  subs = owl_malloc(numSubs * sizeof(ZSubscription_t));

  if (filename==NULL) {
    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".anyone");
  } else {
    strcpy(subsfile, filename);
  }
  
  ret=stat(subsfile, &statbuff);
  if (ret) return(0);

  ret=0;

  ZResetAuthentication();
  count=0;
  file=fopen(subsfile, "r");
  if (file) {
    while ( fgets(buffer, 1024, file)!=NULL ) {
      if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
      
      if (count == numSubs) {
        numSubs *= 2;
        subs = owl_realloc(subs, numSubs * sizeof(ZSubscription_t));
      }

      buffer[strlen(buffer)-1]='\0';
      subs[count].zsub_class=owl_strdup("login");
      subs[count].zsub_recipient=owl_strdup("*");
      if (strchr(buffer, '@')) {
        subs[count].zsub_classinst=owl_strdup(buffer);
      } else {
        subs[count].zsub_classinst=owl_sprintf("%s@%s", buffer, ZGetRealm());
      }

      count++;
    }
    fclose(file);
  } else {
    count=0;
    ret=-1;
  }

  ret = owl_zephyr_loadsubs_helper(subs, count);
  return(ret);
#else
  return(0);
#endif
}
示例#4
0
文件: zephyr.c 项目: arlynap/barnowl
void owl_zephyr_initialize()
{
  int ret;
  struct servent *sp;
  struct sockaddr_in sin;
  ZNotice_t req;
  Code_t code;
  owl_dispatch *dispatch;

  /*
   * Code modified from libzephyr's ZhmStat.c
   *
   * Modified to add the fd to our select loop, rather than hanging
   * until we get an ack.
   */

  if ((ret = ZOpenPort(NULL)) != ZERR_NONE) {
    owl_function_error("Error opening Zephyr port: %s", error_message(ret));
    return;
  }

  (void) memset((char *)&sin, 0, sizeof(struct sockaddr_in));

  sp = getservbyname(HM_SVCNAME, "udp");

  sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK;
  sin.sin_family = AF_INET;

  sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

  (void) memset((char *)&req, 0, sizeof(req));
  req.z_kind = STAT;
  req.z_port = 0;
  req.z_class = HM_STAT_CLASS;
  req.z_class_inst = HM_STAT_CLIENT;
  req.z_opcode = HM_GIMMESTATS;
  req.z_sender = "";
  req.z_recipient = "";
  req.z_default_format = "";
  req.z_message_len = 0;

  if ((code = ZSetDestAddr(&sin)) != ZERR_NONE) {
    owl_function_error("Initializing Zephyr: %s", error_message(code));
    return;
  }

  if ((code = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE) {
    owl_function_error("Initializing Zephyr: %s", error_message(code));
    return;
  }

  dispatch = owl_malloc(sizeof(*dispatch));
  dispatch->fd = ZGetFD();
  dispatch->cfunc = owl_zephyr_finish_initialization;
  dispatch->destroy = (void(*)(owl_dispatch*))owl_free;

  owl_select_add_dispatch(dispatch);
}
示例#5
0
文件: fmtext.c 项目: alexmv/barnowl
/* initialize an fmtext with no data */
void owl_fmtext_init_null(owl_fmtext *f)
{
  f->textlen = 0;
  f->bufflen = 5;
  f->textbuff = owl_malloc(5);
  f->textbuff[0] = 0;
  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
  f->default_fgcolor = OWL_COLOR_DEFAULT;
  f->default_bgcolor = OWL_COLOR_DEFAULT;
}
示例#6
0
文件: fmtext.c 项目: alexmv/barnowl
/*** Color Pair manager ***/
void owl_fmtext_init_colorpair_mgr(owl_colorpair_mgr *cpmgr)
{
  /* This could be a bitarray if we wanted to save memory. */
  short i, j;
  cpmgr->next = 8;
  
  /* The test is <= because we allocate COLORS+1 entries. */
  cpmgr->pairs = owl_malloc((COLORS+1) * sizeof(short*));
  for(i = 0; i <= COLORS; i++) {
    cpmgr->pairs[i] = owl_malloc((COLORS+1) * sizeof(short));
    for(j = 0; j <= COLORS; j++) {
      cpmgr->pairs[i][j] = -1;
    }
  }
  if (owl_global_get_hascolors(&g)) {
    for(i = 0; i < 8; i++) {
      short fg, bg;
      if (i >= COLORS) continue;
      pair_content(i, &fg, &bg);
      cpmgr->pairs[fg+1][bg+1] = i;
    }
  }
}
示例#7
0
文件: select.c 项目: arlynap/barnowl
owl_timer *owl_select_add_timer(int after, int interval, void (*cb)(owl_timer *, void *), void (*destroy)(owl_timer*), void *data)
{
  owl_timer *t = owl_malloc(sizeof(owl_timer));
  GList **timers = owl_global_get_timerlist(&g);

  t->time = time(NULL) + after;
  t->interval = interval;
  t->callback = cb;
  t->destroy = destroy;
  t->data = data;

  *timers = g_list_insert_sorted(*timers, t,
                                 (GCompareFunc)_owl_select_timer_cmp);
  return t;
}
示例#8
0
文件: fmtext.c 项目: alexmv/barnowl
/* Make a copy of the fmtext 'src' into 'dst' */
void owl_fmtext_copy(owl_fmtext *dst, const owl_fmtext *src)
{
  int mallocsize;

  if (src->textlen==0) {
    mallocsize=5;
  } else {
    mallocsize=src->textlen+2;
  }
  dst->textlen=src->textlen;
  dst->bufflen=mallocsize;
  dst->textbuff=owl_malloc(mallocsize);
  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
  dst->default_attrs = src->default_attrs;
  dst->default_fgcolor = src->default_fgcolor;
  dst->default_bgcolor = src->default_bgcolor;
}
示例#9
0
void owl_variable_dict_newvar_bool(owl_vardict * vd, char *name, char *summ, char * desc, int initval) {
  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_BOOL);
  if(old) {
    owl_variable_update(old, summ, desc);
    old->ival_default = initval;
  } else {
    owl_variable * var = owl_variable_newvar(name, summ, desc);
    var->type = OWL_VARIABLE_BOOL;
    var->ival_default = initval;
    var->validate_fn = owl_variable_bool_validate_default;
    var->set_fn = owl_variable_bool_set_default;
    var->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
    var->get_fn = owl_variable_get_default;
    var->get_tostring_fn = owl_variable_bool_get_tostring_default;
    var->free_fn = owl_variable_free_default;
    var->val = owl_malloc(sizeof(int));
    var->set_fn(var, &initval);
    owl_variable_dict_add_variable(vd, var);
  }
}
示例#10
0
文件: zephyr.c 项目: arlynap/barnowl
void owl_zephyr_finish_initialization(owl_dispatch *d) {
  Code_t code;

  owl_select_remove_dispatch(d->fd);

  ZClosePort();

  if ((code = ZInitialize()) != ZERR_NONE) {
    owl_function_error("Initializing Zephyr: %s", error_message(code));
    return;
  }

  if ((code = ZOpenPort(NULL)) != ZERR_NONE) {
    owl_function_error("Initializing Zephyr: %s", error_message(code));
    return;
  }

  d = owl_malloc(sizeof(owl_dispatch));
  d->fd = ZGetFD();
  d->cfunc = &owl_zephyr_process_events;
  d->destroy = NULL;
  owl_select_add_dispatch(d);
  owl_global_set_havezephyr(&g);

  if(g.load_initial_subs) {
    owl_zephyr_load_initial_subs();
  }
  while(deferred_subs != NULL) {
    owl_sub_list *subs = deferred_subs->data;
    owl_function_debugmsg("Loading %d deferred subs.", subs->nsubs);
    owl_zephyr_loadsubs_helper(subs->subs, subs->nsubs);
    deferred_subs = g_list_delete_link(deferred_subs, deferred_subs);
    owl_free(subs);
  }

  /* zlog in if we need to */
  if (owl_global_is_startuplogin(&g)) {
    owl_function_debugmsg("startup: doing zlog in");
    owl_zephyr_zlog_in();
  }
}
示例#11
0
文件: zephyr.c 项目: arlynap/barnowl
/* Load default Barnowl subscriptions
 *
 * Returns 0 on success.
 * Return -2 if there is a failure from zephyr to load the subscriptions.
 */
int owl_zephyr_loadbarnowldefaultsubs()
{
#ifdef HAVE_LIBZEPHYR
  ZSubscription_t *subs;
  int subSize = 10; /* Max Barnowl default subs we allow */
  int count, ret;

  subs = owl_malloc(sizeof(ZSubscription_t) * subSize);
  ret = 0;
  ZResetAuthentication();
  count=0;

  subs[count].zsub_class=owl_strdup("message");
  subs[count].zsub_classinst=owl_strdup("*");
  subs[count].zsub_recipient=owl_strdup("%me%");
  count++;

  ret = owl_zephyr_loadsubs_helper(subs, count);
  return(ret);
#else
  return(0);
#endif
}
示例#12
0
文件: fmtext.c 项目: alexmv/barnowl
/* Append the text 'text' to 'f' and interpret the zephyr style
 * formatting syntax to set appropriate attributes.
 */
void owl_fmtext_append_ztext(owl_fmtext *f, const char *text)
{
  int stacksize, curattrs, curcolor;
  const char *ptr, *txtptr, *tmpptr;
  char *buff;
  int attrstack[32], chrstack[32], colorstack[32];

  curattrs=OWL_FMTEXT_ATTR_NONE;
  curcolor=OWL_COLOR_DEFAULT;
  stacksize=0;
  txtptr=text;
  while (1) {
    ptr=strpbrk(txtptr, "@{[<()>]}");
    if (!ptr) {
      /* add all the rest of the text and exit */
      owl_fmtext_append_attr(f, txtptr, curattrs, curcolor, OWL_COLOR_DEFAULT);
      return;
    } else if (ptr[0]=='@') {
      /* add the text up to this point then deal with the stack */
      buff=owl_malloc(ptr-txtptr+20);
      strncpy(buff, txtptr, ptr-txtptr);
      buff[ptr-txtptr]='\0';
      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
      owl_free(buff);

      /* update pointer to point at the @ */
      txtptr=ptr;

      /* now the stack */

      /* if we've hit our max stack depth, print the @ and move on */
      if (stacksize==32) {
        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
        txtptr++;
        continue;
      }

      /* if it's an @@, print an @ and continue */
      if (txtptr[1]=='@') {
        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
        txtptr+=2;
        continue;
      }
        
      /* if there's no opener, print the @ and continue */
      tmpptr=strpbrk(txtptr, "(<[{ ");
      if (!tmpptr || tmpptr[0]==' ') {
        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
        txtptr++;
        continue;
      }

      /* check what command we've got, push it on the stack, start
         using it, and continue ... unless it's a color command */
      buff=owl_malloc(tmpptr-ptr+20);
      strncpy(buff, ptr, tmpptr-ptr);
      buff[tmpptr-ptr]='\0';
      if (!strcasecmp(buff, "@bold")) {
        attrstack[stacksize]=OWL_FMTEXT_ATTR_BOLD;
        chrstack[stacksize]=tmpptr[0];
	colorstack[stacksize]=curcolor;
        stacksize++;
        curattrs|=OWL_FMTEXT_ATTR_BOLD;
        txtptr+=6;
        owl_free(buff);
        continue;
      } else if (!strcasecmp(buff, "@b")) {
        attrstack[stacksize]=OWL_FMTEXT_ATTR_BOLD;
        chrstack[stacksize]=tmpptr[0];
	colorstack[stacksize]=curcolor;
        stacksize++;
        curattrs|=OWL_FMTEXT_ATTR_BOLD;
        txtptr+=3;
        owl_free(buff);
        continue;
      } else if (!strcasecmp(buff, "@i")) {
        attrstack[stacksize]=OWL_FMTEXT_ATTR_UNDERLINE;
        chrstack[stacksize]=tmpptr[0];
	colorstack[stacksize]=curcolor;
        stacksize++;
        curattrs|=OWL_FMTEXT_ATTR_UNDERLINE;
        txtptr+=3;
        owl_free(buff);
        continue;
      } else if (!strcasecmp(buff, "@italic")) {
        attrstack[stacksize]=OWL_FMTEXT_ATTR_UNDERLINE;
        chrstack[stacksize]=tmpptr[0];
	colorstack[stacksize]=curcolor;
        stacksize++;
        curattrs|=OWL_FMTEXT_ATTR_UNDERLINE;
        txtptr+=8;
        owl_free(buff);
        continue;
      } else if (!strcasecmp(buff, "@")) {
	attrstack[stacksize]=OWL_FMTEXT_ATTR_NONE;
	chrstack[stacksize]=tmpptr[0];
	colorstack[stacksize]=curcolor;
        stacksize++;
        txtptr+=2;
        owl_free(buff);
        continue;

        /* if it's a color read the color, set the current color and
           continue */
      } else if (!strcasecmp(buff, "@color") 
                 && owl_global_get_hascolors(&g)
                 && owl_global_is_colorztext(&g)) {
        owl_free(buff);
        txtptr+=7;
        tmpptr=strpbrk(txtptr, "@{[<()>]}");
        if (tmpptr &&
            ((txtptr[-1]=='(' && tmpptr[0]==')') ||
             (txtptr[-1]=='<' && tmpptr[0]=='>') ||
             (txtptr[-1]=='[' && tmpptr[0]==']') ||
             (txtptr[-1]=='{' && tmpptr[0]=='}'))) {

          /* grab the color name */
          buff=owl_malloc(tmpptr-txtptr+20);
          strncpy(buff, txtptr, tmpptr-txtptr);
          buff[tmpptr-txtptr]='\0';

          /* set it as the current color */
          curcolor=owl_util_string_to_color(buff);
          if (curcolor == OWL_COLOR_INVALID)
	      curcolor = OWL_COLOR_DEFAULT;
          owl_free(buff);
          txtptr=tmpptr+1;
          continue;

        } else {

        }

      } else {
        /* if we didn't understand it, we'll print it.  This is different from zwgc
         * but zwgc seems to be smarter about some screw cases than I am
         */
        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
        txtptr++;
        continue;
      }

    } else if (ptr[0]=='}' || ptr[0]==']' || ptr[0]==')' || ptr[0]=='>') {
      /* add the text up to this point first */
      buff=owl_malloc(ptr-txtptr+20);
      strncpy(buff, txtptr, ptr-txtptr);
      buff[ptr-txtptr]='\0';
      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
      owl_free(buff);

      /* now deal with the closer */
      txtptr=ptr;

      /* first, if the stack is empty we must bail (just print and go) */
      if (stacksize==0) {
        buff=owl_malloc(5);
        buff[0]=ptr[0];
        buff[1]='\0';
        owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
        owl_free(buff);
        txtptr++;
        continue;
      }

      /* if the closing char is what's on the stack, turn off the
         attribue and pop the stack */
      if ((ptr[0]==')' && chrstack[stacksize-1]=='(') ||
          (ptr[0]=='>' && chrstack[stacksize-1]=='<') ||
          (ptr[0]==']' && chrstack[stacksize-1]=='[') ||
          (ptr[0]=='}' && chrstack[stacksize-1]=='{')) {
        int i;
        stacksize--;
        curattrs=OWL_FMTEXT_ATTR_NONE;
	curcolor = colorstack[stacksize];
        for (i=0; i<stacksize; i++) {
          curattrs|=attrstack[i];
        }
        txtptr+=1;
        continue;
      } else {
        /* otherwise print and continue */
        buff=owl_malloc(5);
        buff[0]=ptr[0];
        buff[1]='\0';
        owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
        owl_free(buff);
        txtptr++;
        continue;
      }
    } else {
      /* we've found an unattached opener, print everything and move on */
      buff=owl_malloc(ptr-txtptr+20);
      strncpy(buff, txtptr, ptr-txtptr+1);
      buff[ptr-txtptr+1]='\0';
      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
      owl_free(buff);
      txtptr=ptr+1;
      continue;
    }
  }
}
示例#13
0
int owl_variable_dict_setup(owl_vardict *vd) {
  owl_variable *var, *cur;
  if (owl_dict_create(vd)) return(-1);
  for (var = variables_to_init; var->name != NULL; var++) {
    cur = owl_malloc(sizeof(owl_variable));
    memcpy(cur, var, sizeof(owl_variable));
    switch (cur->type) {
    case OWL_VARIABLE_OTHER:
      cur->set_fn(cur, cur->pval_default);
      break;
    case OWL_VARIABLE_STRING:
      if (!cur->validate_fn) 
	cur->validate_fn = owl_variable_string_validate_default;
      if (!cur->set_fn) 
	cur->set_fn = owl_variable_string_set_default;
      if (!cur->set_fromstring_fn) 
	cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
      if (!cur->get_fn) 
	cur->get_fn = owl_variable_get_default;
      if (!cur->get_tostring_fn) 
	cur->get_tostring_fn = owl_variable_string_get_tostring_default;      
      if (!cur->free_fn) 
	cur->free_fn = owl_variable_free_default;
      cur->set_fn(cur, cur->pval_default);
      break;
    case OWL_VARIABLE_BOOL:
      if (!cur->validate_fn) 
	cur->validate_fn = owl_variable_bool_validate_default;
      if (!cur->set_fn) 
	cur->set_fn = owl_variable_bool_set_default;
      if (!cur->set_fromstring_fn) 
	cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
      if (!cur->get_fn) 
	cur->get_fn = owl_variable_get_default;
      if (!cur->get_tostring_fn) 
	cur->get_tostring_fn = owl_variable_bool_get_tostring_default;      
      if (!cur->free_fn) 
	cur->free_fn = owl_variable_free_default;
      cur->val = owl_malloc(sizeof(int));
      cur->set_fn(cur, &cur->ival_default);
      break;
    case OWL_VARIABLE_INT:
      if (!cur->validate_fn) 
	cur->validate_fn = owl_variable_int_validate_default;
      if (!cur->set_fn) 
	cur->set_fn = owl_variable_int_set_default;
      if (!cur->set_fromstring_fn) 
	cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
      if (!cur->get_fn) 
	cur->get_fn = owl_variable_get_default;
      if (!cur->get_tostring_fn) 
	cur->get_tostring_fn = owl_variable_int_get_tostring_default;      
      if (!cur->free_fn) 
	cur->free_fn = owl_variable_free_default;
      cur->val = owl_malloc(sizeof(int));
      cur->set_fn(cur, &cur->ival_default);
      break;
    default:
      fprintf(stderr, "owl_variable_setup: invalid variable type\n");
      return(-2);
    }
    owl_dict_insert_element(vd, cur->name, (void*)cur, NULL);
  }
  return 0;
}
示例#14
0
文件: zephyr.c 项目: arlynap/barnowl
/* Load zephyr subscriptions from 'filename'.  If 'filename' is NULL,
 * the default file $HOME/.zephyr.subs will be used.
 *
 * Returns 0 on success.  If the file does not exist, return -1 if
 * 'error_on_nofile' is 1, otherwise return 0.  Return -1 if the file
 * exists but can not be read.  Return -2 if there is a failure from
 * zephyr to load the subscriptions.
 */
int owl_zephyr_loadsubs(char *filename, int error_on_nofile)
{
#ifdef HAVE_LIBZEPHYR
  FILE *file;
  char *tmp, *start;
  char buffer[1024], subsfile[1024];
  ZSubscription_t *subs;
  int subSize = 1024;
  int count, ret;
  struct stat statbuff;

  subs = owl_malloc(sizeof(ZSubscription_t) * subSize);
  if (filename==NULL) {
    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
  } else {
    strcpy(subsfile, filename);
  }

  ret=stat(subsfile, &statbuff);
  if (ret) {
    if (error_on_nofile==1) return(-1);
    return(0);
  }

  ZResetAuthentication();
  count=0;
  file=fopen(subsfile, "r");
  if (!file) return(-1);
  while ( fgets(buffer, 1024, file)!=NULL ) {
    if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
    
    if (buffer[0]=='-') {
      start=buffer+1;
    } else {
      start=buffer;
    }
    
    if (count >= subSize) {
      subSize *= 2;
      subs = owl_realloc(subs, sizeof(ZSubscription_t) * subSize);
    }
    
    /* add it to the list of subs */
    if ((tmp=(char *) strtok(start, ",\n\r"))==NULL) continue;
    subs[count].zsub_class=owl_strdup(tmp);
    if ((tmp=(char *) strtok(NULL, ",\n\r"))==NULL) continue;
    subs[count].zsub_classinst=owl_strdup(tmp);
    if ((tmp=(char *) strtok(NULL, " \t\n\r"))==NULL) continue;
    subs[count].zsub_recipient=owl_strdup(tmp);
    
    /* if it started with '-' then add it to the global punt list, and
     * remove it from the list of subs. */
    if (buffer[0]=='-') {
      owl_function_zpunt(subs[count].zsub_class, subs[count].zsub_classinst, subs[count].zsub_recipient, 0);
      owl_free(subs[count].zsub_class);
      owl_free(subs[count].zsub_classinst);
      owl_free(subs[count].zsub_recipient);
    }
    else {
      count++;
    }
  }
  fclose(file);

  ret = owl_zephyr_loadsubs_helper(subs, count);
  return(ret);
#else
  return(0);
#endif
}
示例#15
0
/* XXX TODO: Messages should round-trip properly between
   message2hashref and hashref2message. Currently we lose
   zephyr-specific properties stored in the ZNotice_t

   This has been somewhat addressed, but is still not lossless.
 */
owl_message * owl_perlconfig_hashref2message(SV *msg)
{
  owl_message * m;
  HE * ent;
  I32 count, len;
  const char *key,*val;
  HV * hash;
  struct tm tm;

  hash = (HV*)SvRV(msg);

  m = owl_malloc(sizeof(owl_message));
  owl_message_init(m);

  count = hv_iterinit(hash);
  while((ent = hv_iternext(hash))) {
    key = hv_iterkey(ent, &len);
    val = SvPV_nolen(hv_iterval(hash, ent));
    if(!strcmp(key, "type")) {
      owl_message_set_type(m, val);
    } else if(!strcmp(key, "direction")) {
      owl_message_set_direction(m, owl_message_parse_direction(val));
    } else if(!strcmp(key, "private")) {
      SV * v = hv_iterval(hash, ent);
      if(SvTRUE(v)) {
        owl_message_set_isprivate(m);
      }
    } else if (!strcmp(key, "hostname")) {
      owl_message_set_hostname(m, val);
    } else if (!strcmp(key, "zwriteline")) {
      owl_message_set_zwriteline(m, val);
    } else if (!strcmp(key, "time")) {
      m->timestr = owl_strdup(val);
      strptime(val, "%a %b %d %T %Y", &tm);
      m->time = mktime(&tm);
    } else {
      owl_message_set_attribute(m, key, val);
    }
  }
  if(owl_message_is_type_admin(m)) {
    if(!owl_message_get_attribute_value(m, "adminheader"))
      owl_message_set_attribute(m, "adminheader", "");
  }
#ifdef HAVE_LIBZEPHYR
  if (owl_message_is_type_zephyr(m)) {
    ZNotice_t *n = &(m->notice);
    n->z_kind = ACKED;
    n->z_port = 0;
    n->z_auth = ZAUTH_NO;
    n->z_checked_auth = 0;
    n->z_class = zstr(owl_message_get_class(m));
    n->z_class_inst = zstr(owl_message_get_instance(m));
    n->z_opcode = zstr(owl_message_get_opcode(m));
    n->z_sender = zstr(owl_message_get_sender(m));
    n->z_recipient = zstr(owl_message_get_recipient(m));
    n->z_default_format = zstr("[zephyr created from perl]");
    n->z_multinotice = zstr("[zephyr created from perl]");
    n->z_num_other_fields = 0;
    n->z_message = owl_sprintf("%s%c%s", owl_message_get_zsig(m), '\0', owl_message_get_body(m));
    n->z_message_len = strlen(owl_message_get_zsig(m)) + strlen(owl_message_get_body(m)) + 1;
  }
#endif
  return m;
}