Index: readconfig.c
===================================================================
--- readconfig.c	(revision 7d4fbcdd0df83802711454fdafce2c9d592bf431)
+++ readconfig.c	(revision 7d4fbcdd0df83802711454fdafce2c9d592bf431)
@@ -0,0 +1,213 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "owl.h"
+#include <perl.h>
+
+int owl_readconfig(char *file) {
+  int ret;
+  PerlInterpreter *p;
+  char buff[1024], filename[1024];
+  char *embedding[5];
+  struct stat statbuff;
+
+  if (file==NULL) {
+    sprintf(filename, "%s/%s", getenv("HOME"), ".owlconf");
+  } else {
+    strcpy(filename, file);
+  }
+
+  embedding[0]="";
+  embedding[1]=filename;
+  embedding[2]=0;
+
+  /* create and initialize interpreter */
+  p=perl_alloc();
+  owl_global_set_perlinterp(&g, (void*)p);
+  perl_construct(p);
+
+  owl_global_set_no_have_config(&g);
+
+  ret=stat(filename, &statbuff);
+  if (ret) {
+    return(0);
+  }
+
+  ret=perl_parse(p, NULL, 2, embedding, NULL);
+  if (ret) return(-1);
+
+  ret=perl_run(p);
+  if (ret) return(-1);
+
+  owl_global_set_have_config(&g);
+
+  /* create variables */
+  perl_get_sv("owl::id", TRUE);
+  perl_get_sv("owl::class", TRUE);
+  perl_get_sv("owl::instance", TRUE);
+  perl_get_sv("owl::recipient", TRUE);
+  perl_get_sv("owl::sender", TRUE);
+  perl_get_sv("owl::realm", TRUE);
+  perl_get_sv("owl::opcode", TRUE);
+  perl_get_sv("owl::zsig", TRUE);
+  perl_get_sv("owl::msg", TRUE);
+  perl_get_sv("owl::time", TRUE);
+  perl_get_sv("owl::host", TRUE);
+  perl_get_av("owl::fields", TRUE);
+  
+  /* load in owl_command() */
+  strcpy(buff, "sub owl::command {                           \n");
+  strcat(buff, "  my $command = shift;                       \n");
+  strcat(buff, "  push @owl::commands, $command;             \n");
+  strcat(buff, "}                                            \n");
+  perl_eval_pv(buff, FALSE);
+
+
+  /* check if we have the formatting function */
+  if (perl_get_cv("owl::format_msg", FALSE)) {
+    owl_global_set_config_format(&g, 1);
+  }
+  return(0);
+}
+
+
+/* caller is responsible for freeing returned string */
+char *owl_config_execute(char *line) {
+  STRLEN n_a;
+  SV *command, *response;
+  AV *commands;
+  int numcommands, i;
+  char *out, *preout;
+
+  if (!owl_global_have_config(&g)) return NULL;
+
+  /* execute the subroutine */
+  response = perl_eval_pv(line, FALSE);
+
+  preout=SvPV(response, n_a);
+  /* leave enough space in case we have to add a newline */
+  out = owl_malloc(strlen(preout)+2);
+  strcpy(out, preout);
+  if (!strlen(out) || out[strlen(out)-1]!='\n') {
+    strcat(out, "\n");
+  }
+
+  /* execute all the commands, cleaning up the arrays as we go */
+  commands=perl_get_av("owl::commands", TRUE);
+  numcommands=av_len(commands)+1;
+  for (i=0; i<numcommands; i++) {
+    command=av_shift(commands);
+    owl_function_command_norv(SvPV(command, n_a));
+  }
+  av_undef(commands);
+
+  return(out);
+}
+
+char *owl_config_getmsg(owl_message *m, int mode) {
+  /* if mode==1 we are doing message formatting.  The returned
+   * formatted message needs to be freed by the caller.
+   *
+   * if mode==0 we are just doing the message-has-been-received
+   * thing.
+  */
+
+  int i, j, len;
+  char *ptr, *ptr2;
+  ZNotice_t *n;
+
+  if (!owl_global_have_config(&g)) return("");
+
+  /* set owl::msg */
+  n=owl_message_get_notice(m);
+  ptr=owl_zephyr_get_message(n, &len);
+  ptr2=owl_malloc(len+20);
+  memcpy(ptr2, ptr, len);
+  ptr2[len]='\0';
+  if (ptr2[len-1]!='\n') {
+    strcat(ptr2, "\n");
+  }
+  sv_setpv(perl_get_sv("owl::msg", TRUE), ptr2);
+  owl_free(ptr2);
+
+  /* set owl::zsig */
+  ptr=owl_zephyr_get_zsig(n, &len);
+  if (len>0) {
+    ptr2=owl_malloc(len+20);
+    memcpy(ptr2, ptr, len);
+    ptr2[len]='\0';
+    if (ptr2[len-1]=='\n') {  /* do we really need this? */
+      ptr2[len-1]='\0';
+    }
+    sv_setpv(perl_get_sv("owl::zsig", TRUE), ptr2);
+    owl_free(ptr2);
+  } else {
+    sv_setpv(perl_get_sv("owl::zsig", TRUE), "");
+  }
+
+  /* set owl::type */
+  if (owl_message_is_zephyr(m)) {
+    sv_setpv(perl_get_sv("owl::type", TRUE), "zephyr");
+  } else if (owl_message_is_admin(m)) {
+    sv_setpv(perl_get_sv("owl::type", TRUE), "admin");
+  } else {
+    sv_setpv(perl_get_sv("owl::type", TRUE), "unknown");
+  }
+
+  /* set everything else */
+  sv_setpv(perl_get_sv("owl::class", TRUE), owl_message_get_class(m));
+  sv_setpv(perl_get_sv("owl::instance", TRUE), owl_message_get_instance(m));
+  sv_setpv(perl_get_sv("owl::sender", TRUE), owl_message_get_sender(m));
+  sv_setpv(perl_get_sv("owl::realm", TRUE), owl_message_get_realm(m));
+  sv_setpv(perl_get_sv("owl::recipient", TRUE), owl_message_get_recipient(m));
+  sv_setpv(perl_get_sv("owl::opcode", TRUE), owl_message_get_opcode(m));
+  sv_setpv(perl_get_sv("owl::time", TRUE), owl_message_get_timestr(m));
+  sv_setpv(perl_get_sv("owl::host", TRUE), owl_message_get_hostname(m));
+  sv_setiv(perl_get_sv("owl::id", TRUE), owl_message_get_id(m));
+
+  /* free old @fields ? */
+  /* I don't think I need to do this, but ask marc to make sure */
+  /*
+  j=av_len(perl_get_av("fields", TRUE));
+  for (i=0; i<j; i++) {
+    tmpsv=av_pop(perl_get_av("fields", TRUE));
+    SvREFCNT_dec(tmpsv);
+  }
+  */
+
+  /* set owl::fields */
+  av_clear(perl_get_av("owl::fields", TRUE));
+  j=owl_zephyr_get_num_fields(n);
+  for (i=0; i<j; i++) {
+    ptr=owl_zephyr_get_field(n, i+1, &len);
+    ptr2=owl_malloc(len+10);
+    memcpy(ptr2, ptr, len);
+    ptr2[len]='\0';
+    av_push(perl_get_av("owl::fields", TRUE), newSVpvn(ptr2, len));
+    owl_free(ptr2);
+  }
+
+  /* for backwards compatibilty, because I'm an idiot */
+  av_clear(perl_get_av("fields", TRUE));
+  j=owl_zephyr_get_num_fields(n);
+  for (i=0; i<j; i++) {
+    ptr=owl_zephyr_get_field(n, i+1, &len);
+    ptr2=owl_malloc(len+10);
+    memcpy(ptr2, ptr, len);
+    ptr2[len]='\0';
+    av_push(perl_get_av("fields", TRUE), newSVpvn(ptr2, len));
+    owl_free(ptr2);
+  }
+
+  /* run the procedure corresponding to the mode */
+  if (mode==1) {
+    return(owl_config_execute("owl::format_msg();"));
+  } else {
+    ptr=owl_config_execute("owl::receive_msg();");
+    if (ptr) owl_free(ptr);
+    return(NULL);
+  }
+}
