source: readconfig.c @ 039213e

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 039213e was 8ee73f8d, checked in by Erik Nygren <nygren@mit.edu>, 19 years ago
Fixed a memory reference bug in delete and undelete commands. Added support for perl to call directly back into owl. Changed the implementation of owl::command("...") to immediately call back into owl. This allows perl to get the return value of strings returned by owl commands. Added the getview command which returns the name of the current view's filter. Added the getvar command which returns the value of a variable. Added an example to examples/owlconf.erik which uses TAB to narrow and restore the view. Added an example to examples/owlconf.erik which uses M-c to color messages matching the current one green.
  • Property mode set to 100644
File size: 5.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <errno.h>
7#include "owl.h"
8#include <perl.h>
9
10static const char fileIdent[] = "$Id$";
11
12
13
14EXTERN_C void boot_owl (pTHX_ CV* cv);
15
16static void owl_perl_xs_init(pTHX) {
17  char *file = __FILE__;
18  dXSUB_SYS;
19  {
20    newXS("owl::bootstrap", boot_owl, file);
21  }
22}
23
24
25int owl_readconfig(char *file) {
26  int ret;
27  PerlInterpreter *p;
28  char *codebuff, filename[1024];
29  char *embedding[5];
30  struct stat statbuff;
31
32  if (file==NULL) {
33    sprintf(filename, "%s/%s", getenv("HOME"), ".owlconf");
34  } else {
35    strcpy(filename, file);
36  }
37  embedding[0]="";
38  embedding[1]=filename;
39  embedding[2]=0;
40
41  /* create and initialize interpreter */
42  p=perl_alloc();
43  owl_global_set_perlinterp(&g, (void*)p);
44  perl_construct(p);
45
46  owl_global_set_no_have_config(&g);
47
48  ret=stat(filename, &statbuff);
49  if (ret) {
50    return(0);
51  }
52
53  ret=perl_parse(p, owl_perl_xs_init, 2, embedding, NULL);
54  if (ret) return(-1);
55
56  ret=perl_run(p);
57  if (ret) return(-1);
58
59  owl_global_set_have_config(&g);
60
61  /* create variables */
62  perl_get_sv("owl::id", TRUE);
63  perl_get_sv("owl::class", TRUE);
64  perl_get_sv("owl::instance", TRUE);
65  perl_get_sv("owl::recipient", TRUE);
66  perl_get_sv("owl::sender", TRUE);
67  perl_get_sv("owl::realm", TRUE);
68  perl_get_sv("owl::opcode", TRUE);
69  perl_get_sv("owl::zsig", TRUE);
70  perl_get_sv("owl::msg", TRUE);
71  perl_get_sv("owl::time", TRUE);
72  perl_get_sv("owl::host", TRUE);
73  perl_get_av("owl::fields", TRUE);
74 
75  /* perl bootstrapping code*/
76  codebuff = 
77    "                                             \n"
78    "package owl;                                 \n"
79    "                                             \n"
80    "bootstrap owl 0.01;                          \n"
81    "                                             \n"
82    "package main;                                \n";
83
84  perl_eval_pv(codebuff, FALSE);
85
86
87  /* check if we have the formatting function */
88  if (perl_get_cv("owl::format_msg", FALSE)) {
89    owl_global_set_config_format(&g, 1);
90  }
91  return(0);
92}
93
94
95/* caller is responsible for freeing returned string */
96char *owl_config_execute(char *line) {
97  STRLEN len;
98  SV *response;
99  char *out, *preout;
100
101  if (!owl_global_have_config(&g)) return NULL;
102
103  /* execute the subroutine */
104  response = perl_eval_pv(line, FALSE);
105
106  preout=SvPV(response, len);
107  /* leave enough space in case we have to add a newline */
108  out = owl_malloc(strlen(preout)+2);
109  strncpy(out, preout, len);
110  out[len] = '\0';
111  if (!strlen(out) || out[strlen(out)-1]!='\n') {
112    strcat(out, "\n");
113  }
114
115  return(out);
116}
117
118char *owl_config_getmsg(owl_message *m, int mode) {
119  /* if mode==1 we are doing message formatting.  The returned
120   * formatted message needs to be freed by the caller.
121   *
122   * if mode==0 we are just doing the message-has-been-received
123   * thing.
124  */
125
126  int i, j, len;
127  char *ptr, *ptr2;
128  ZNotice_t *n;
129
130  if (!owl_global_have_config(&g)) return("");
131
132  /* set owl::msg */
133  n=owl_message_get_notice(m);
134  ptr=owl_zephyr_get_message(n, &len);
135  ptr2=owl_malloc(len+20);
136  memcpy(ptr2, ptr, len);
137  ptr2[len]='\0';
138  if (ptr2[len-1]!='\n') {
139    strcat(ptr2, "\n");
140  }
141  sv_setpv(perl_get_sv("owl::msg", TRUE), ptr2);
142  owl_free(ptr2);
143
144  /* set owl::zsig */
145  ptr=owl_zephyr_get_zsig(n, &len);
146  if (len>0) {
147    ptr2=owl_malloc(len+20);
148    memcpy(ptr2, ptr, len);
149    ptr2[len]='\0';
150    if (ptr2[len-1]=='\n') {  /* do we really need this? */
151      ptr2[len-1]='\0';
152    }
153    sv_setpv(perl_get_sv("owl::zsig", TRUE), ptr2);
154    owl_free(ptr2);
155  } else {
156    sv_setpv(perl_get_sv("owl::zsig", TRUE), "");
157  }
158
159  /* set owl::type */
160  if (owl_message_is_zephyr(m)) {
161    sv_setpv(perl_get_sv("owl::type", TRUE), "zephyr");
162  } else if (owl_message_is_admin(m)) {
163    sv_setpv(perl_get_sv("owl::type", TRUE), "admin");
164  } else {
165    sv_setpv(perl_get_sv("owl::type", TRUE), "unknown");
166  }
167
168  /* set everything else */
169  sv_setpv(perl_get_sv("owl::class", TRUE), owl_message_get_class(m));
170  sv_setpv(perl_get_sv("owl::instance", TRUE), owl_message_get_instance(m));
171  sv_setpv(perl_get_sv("owl::sender", TRUE), owl_message_get_sender(m));
172  sv_setpv(perl_get_sv("owl::realm", TRUE), owl_message_get_realm(m));
173  sv_setpv(perl_get_sv("owl::recipient", TRUE), owl_message_get_recipient(m));
174  sv_setpv(perl_get_sv("owl::opcode", TRUE), owl_message_get_opcode(m));
175  sv_setpv(perl_get_sv("owl::time", TRUE), owl_message_get_timestr(m));
176  sv_setpv(perl_get_sv("owl::host", TRUE), owl_message_get_hostname(m));
177  sv_setiv(perl_get_sv("owl::id", TRUE), owl_message_get_id(m));
178
179  /* free old @fields ? */
180  /* I don't think I need to do this, but ask marc to make sure */
181  /*
182  j=av_len(perl_get_av("fields", TRUE));
183  for (i=0; i<j; i++) {
184    tmpsv=av_pop(perl_get_av("fields", TRUE));
185    SvREFCNT_dec(tmpsv);
186  }
187  */
188
189  /* set owl::fields */
190  av_clear(perl_get_av("owl::fields", TRUE));
191  j=owl_zephyr_get_num_fields(n);
192  for (i=0; i<j; i++) {
193    ptr=owl_zephyr_get_field(n, i+1, &len);
194    ptr2=owl_malloc(len+10);
195    memcpy(ptr2, ptr, len);
196    ptr2[len]='\0';
197    av_push(perl_get_av("owl::fields", TRUE), newSVpvn(ptr2, len));
198    owl_free(ptr2);
199  }
200
201  /* for backwards compatibilty, because I'm an idiot */
202  av_clear(perl_get_av("fields", TRUE));
203  j=owl_zephyr_get_num_fields(n);
204  for (i=0; i<j; i++) {
205    ptr=owl_zephyr_get_field(n, i+1, &len);
206    ptr2=owl_malloc(len+10);
207    memcpy(ptr2, ptr, len);
208    ptr2[len]='\0';
209    av_push(perl_get_av("fields", TRUE), newSVpvn(ptr2, len));
210    owl_free(ptr2);
211  }
212
213  /* run the procedure corresponding to the mode */
214  if (mode==1) {
215    return(owl_config_execute("owl::format_msg();"));
216  } else {
217    ptr=owl_config_execute("owl::receive_msg();");
218    if (ptr) owl_free(ptr);
219    return(NULL);
220  }
221}
222
Note: See TracBrowser for help on using the repository browser.