source: zwrite.c @ a52d13a

release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since a52d13a was a52d13a, checked in by Nelson Elhage <nelhage@mit.edu>, 9 years ago
zephyr: Expand tabs in outgoing messages. While we're at it, refactor owl_zwrite_create_from_line slightly in a way that fixes 'zwrite -C user1 user2 -m message' to include the CC: line.
  • Property mode set to 100644
File size: 8.7 KB
Line 
1#include <string.h>
2#include <pwd.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id$";
8
9int owl_zwrite_create_from_line(owl_zwrite *z, char *line)
10{
11  int argc, badargs, myargc, i, len;
12  char **argv, **myargv;
13  char *msg = NULL;
14
15  badargs=0;
16 
17  /* start with null entries */
18  z->realm=NULL;
19  z->class=NULL;
20  z->inst=NULL;
21  z->opcode=NULL;
22  z->zsig=NULL;
23  z->message=NULL;
24  z->cc=0;
25  z->noping=0;
26  owl_list_create(&(z->recips));
27
28  /* parse the command line for options */
29  argv=myargv=owl_parseline(line, &argc);
30  if (argc<0) {
31    owl_function_error("Unbalanced quotes in zwrite");
32    return(-1);
33  }
34  myargc=argc;
35  if (myargc && *(myargv[0])!='-') {
36    myargc--;
37    myargv++;
38  }
39  while (myargc) {
40    if (!strcmp(myargv[0], "-c")) {
41      if (myargc<2) {
42        badargs=1;
43        break;
44      }
45      z->class=owl_validate_utf8(myargv[1]);
46      myargv+=2;
47      myargc-=2;
48    } else if (!strcmp(myargv[0], "-i")) {
49      if (myargc<2) {
50        badargs=1;
51        break;
52      }
53      z->inst=owl_validate_utf8(myargv[1]);
54      myargv+=2;
55      myargc-=2;
56    } else if (!strcmp(myargv[0], "-r")) {
57      if (myargc<2) {
58        badargs=1;
59        break;
60      }
61      z->realm=owl_validate_utf8(myargv[1]);
62      myargv+=2;
63      myargc-=2;
64    } else if (!strcmp(myargv[0], "-s")) {
65      if (myargc<2) {
66        badargs=1;
67        break;
68      }
69      z->zsig=owl_validate_utf8(myargv[1]);
70      myargv+=2;
71      myargc-=2;
72    } else if (!strcmp(myargv[0], "-O")) {
73      if (myargc<2) {
74        badargs=1;
75        break;
76      }
77      z->opcode=owl_validate_utf8(myargv[1]);
78      myargv+=2;
79      myargc-=2;
80    } else if (!strcmp(myargv[0], "-m")) {
81      if (myargc<2) {
82        badargs=1;
83        break;
84      }
85      /* we must already have users or a class or an instance */
86      if (owl_list_get_size(&(z->recips))<1 && (!z->class) && (!z->inst)) {
87        badargs=1;
88        break;
89      }
90
91      /* Once we have -m, gobble up everything else on the line */
92      myargv++;
93      myargc--;
94      len = 0;
95      for (i=0;i<myargc;i++) {
96        len += strlen(myargv[i-1]) + 1;
97      }
98      msg = owl_malloc(len);
99      msg[0] = '\0';
100      while (myargc) {
101        strcat(msg, myargv[0]);
102        strcat(msg, " ");
103        myargc--;
104        myargv++;
105      }
106      msg[strlen(msg)-1] = '\0';
107      break;
108    } else if (!strcmp(myargv[0], "-C")) {
109      z->cc=1;
110      myargv++;
111      myargc--;
112    } else if (!strcmp(myargv[0], "-n")) {
113      z->noping=1;
114      myargv++;
115      myargc--;
116    } else {
117      /* anything unattached is a recipient */
118      owl_list_append_element(&(z->recips), owl_validate_utf8(myargv[0]));
119      myargv++;
120      myargc--;
121    }
122  }
123
124  owl_parsefree(argv, argc);
125
126  if (badargs) {
127    return(-1);
128  }
129
130  if (z->class == NULL &&
131      z->inst == NULL &&
132      owl_list_get_size(&(z->recips))==0) {
133    owl_function_error("You must specify a recipient for zwrite");
134    return(-1);
135  }
136
137  /* now deal with defaults */
138  if (z->class==NULL) z->class=owl_strdup("message");
139  if (z->inst==NULL) z->inst=owl_strdup("personal");
140  if (z->realm==NULL) z->realm=owl_strdup("");
141  if (z->opcode==NULL) z->opcode=owl_strdup("");
142  /* z->message is allowed to stay NULL */
143
144  if(msg) {
145    owl_zwrite_set_message(z, msg);
146    owl_free(msg);
147  }
148
149  return(0);
150}
151
152void owl_zwrite_populate_zsig(owl_zwrite *z)
153{
154  char *zsigproc, *zsigowlvar, *zsigzvar, *ptr;
155  struct passwd *pw;
156
157  /* get a zsig, if not given */
158  if (z->zsig==NULL) {
159    zsigproc = owl_global_get_zsigproc(&g);
160    zsigowlvar = owl_global_get_zsig(&g);
161    zsigzvar = owl_zephyr_get_variable("zwrite-signature");
162
163    if (zsigowlvar && *zsigowlvar) {
164      z->zsig=owl_validate_utf8(zsigowlvar);
165    } else if (zsigproc && *zsigproc) {
166      FILE *file;
167      char buff[LINE], *openline;
168     
169      /* simple hack for now to nuke stderr */
170      openline=owl_malloc(strlen(zsigproc)+40);
171      strcpy(openline, zsigproc);
172#if !(OWL_STDERR_REDIR)
173      strcat(openline, " 2> /dev/null");
174#endif
175      file=popen(openline, "r");
176      owl_free(openline);
177      if (!file) {
178        if (zsigzvar && *zsigzvar) {
179          z->zsig=owl_validate_utf8(zsigzvar);
180        }
181      } else {
182        z->zsig=owl_malloc(LINE*5);
183        strcpy(z->zsig, "");
184        while (fgets(buff, LINE, file)) { /* wrong sizing */
185          strcat(z->zsig, buff);
186        }
187        pclose(file);
188        if (z->zsig[strlen(z->zsig)-1]=='\n') {
189          z->zsig[strlen(z->zsig)-1]='\0';
190        }
191      }
192    } else if (zsigzvar) {
193      z->zsig=owl_validate_utf8(zsigzvar);
194    } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
195      z->zsig=owl_validate_utf8(pw->pw_gecos);
196      ptr=strchr(z->zsig, ',');
197      if (ptr) {
198        ptr[0]='\0';
199      }
200    }
201  }
202}
203
204void owl_zwrite_send_ping(owl_zwrite *z)
205{
206  int i, j;
207  char *to;
208
209  if (z->noping) return;
210 
211  if (strcasecmp(z->class, "message")) {
212    return;
213  }
214
215  /* if there are no recipients we won't send a ping, which
216     is what we want */
217  j=owl_list_get_size(&(z->recips));
218  for (i=0; i<j; i++) {
219    if (strcmp(z->realm, "")) {
220      to = owl_sprintf("%s@%s", (char *) owl_list_get_element(&(z->recips), i), z->realm);
221    } else {
222      to = owl_strdup(owl_list_get_element(&(z->recips), i));
223    }
224    send_ping(to, z->class, z->inst);
225    owl_free(to);
226  }
227
228}
229
230void owl_zwrite_set_message(owl_zwrite *z, char *msg)
231{
232  int i, j;
233  char *toline = NULL;
234  char *tmp = NULL, *tmp2;
235
236  if (z->message) owl_free(z->message);
237
238  j=owl_list_get_size(&(z->recips));
239  if (j>0 && z->cc) {
240    toline = owl_strdup( "CC: ");
241    for (i=0; i<j; i++) {
242      tmp = toline;
243      if (strcmp(z->realm, "")) {
244        toline = owl_sprintf( "%s%s@%s ", toline, (char *) owl_list_get_element(&(z->recips), i), z->realm);
245      } else {
246        toline = owl_sprintf( "%s%s ", toline, (char *) owl_list_get_element(&(z->recips), i));
247      }
248      owl_free(tmp);
249      tmp = NULL;
250    }
251    tmp = owl_validate_utf8(msg);
252    tmp2 = owl_text_expand_tabs(tmp);
253    z->message=owl_sprintf("%s\n%s", toline, tmp2);
254    owl_free(toline);
255    owl_free(tmp);
256    owl_free(tmp2);
257  } else {
258    tmp=owl_validate_utf8(msg);
259    z->message=owl_text_expand_tabs(tmp);
260    owl_free(tmp);
261  }
262}
263
264char *owl_zwrite_get_message(owl_zwrite *z)
265{
266  if (z->message) return(z->message);
267  return("");
268}
269
270int owl_zwrite_is_message_set(owl_zwrite *z)
271{
272  if (z->message) return(1);
273  return(0);
274}
275
276int owl_zwrite_send_message(owl_zwrite *z)
277{
278  int i, j;
279  char *to = NULL;
280
281  if (z->message==NULL) return(-1);
282
283  j=owl_list_get_size(&(z->recips));
284  if (j>0) {
285    for (i=0; i<j; i++) {
286      if (strcmp(z->realm, "")) {
287        to = owl_sprintf("%s@%s", (char *) owl_list_get_element(&(z->recips), i), z->realm);
288      } else {
289        to = owl_strdup( owl_list_get_element(&(z->recips), i));
290      }
291      send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
292      owl_free(to);
293      to = NULL;
294    }
295  } else {
296    to = owl_sprintf( "@%s", z->realm);
297    send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
298  }
299  owl_free(to);
300  return(0);
301}
302
303int owl_zwrite_create_and_send_from_line(char *cmd, char *msg)
304{
305  owl_zwrite z;
306  int rv;
307  rv=owl_zwrite_create_from_line(&z, cmd);
308  if (rv) return(rv);
309  if (!owl_zwrite_is_message_set(&z)) {
310    owl_zwrite_set_message(&z, msg);
311  }
312  owl_zwrite_populate_zsig(&z);
313  owl_zwrite_send_message(&z);
314  owl_zwrite_free(&z);
315  return(0);
316}
317
318char *owl_zwrite_get_class(owl_zwrite *z)
319{
320  return(z->class);
321}
322
323char *owl_zwrite_get_instance(owl_zwrite *z)
324{
325  return(z->inst);
326}
327
328char *owl_zwrite_get_opcode(owl_zwrite *z)
329{
330  return(z->opcode);
331}
332
333void owl_zwrite_set_opcode(owl_zwrite *z, char *opcode)
334{
335  if (z->opcode) owl_free(z->opcode);
336  z->opcode=owl_validate_utf8(opcode);
337}
338
339char *owl_zwrite_get_realm(owl_zwrite *z)
340{
341  return(z->realm);
342}
343
344char *owl_zwrite_get_zsig(owl_zwrite *z)
345{
346  if (z->zsig) return(z->zsig);
347  return("");
348}
349
350void owl_zwrite_get_recipstr(owl_zwrite *z, char *buff)
351{
352  int i, j;
353
354  strcpy(buff, "");
355  j=owl_list_get_size(&(z->recips));
356  for (i=0; i<j; i++) {
357    strcat(buff, owl_list_get_element(&(z->recips), i));
358    strcat(buff, " ");
359  }
360  buff[strlen(buff)-1]='\0';
361}
362
363int owl_zwrite_get_numrecips(owl_zwrite *z)
364{
365  return(owl_list_get_size(&(z->recips)));
366}
367
368char *owl_zwrite_get_recip_n(owl_zwrite *z, int n)
369{
370  return(owl_list_get_element(&(z->recips), n));
371}
372
373int owl_zwrite_is_personal(owl_zwrite *z)
374{
375  /* return true if at least one of the recipients is personal */
376  int i, j;
377  char *foo;
378
379  j=owl_list_get_size(&(z->recips));
380  for (i=0; i<j; i++) {
381    foo=owl_list_get_element(&(z->recips), i);
382    if (foo[0]!='@') return(1);
383  }
384  return(0);
385}
386
387void owl_zwrite_free(owl_zwrite *z)
388{
389  owl_list_free_all(&(z->recips), &owl_free);
390  if (z->class) owl_free(z->class);
391  if (z->inst) owl_free(z->inst);
392  if (z->opcode) owl_free(z->opcode);
393  if (z->realm) owl_free(z->realm);
394  if (z->message) owl_free(z->message);
395  if (z->zsig) owl_free(z->zsig);
396}
Note: See TracBrowser for help on using the repository browser.