]> mj.ucw.cz Git - umpf.git/blob - umpf.c
fix many little bugs, release 0.1
[umpf.git] / umpf.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <pwd.h>
5 #include <getopt.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <signal.h>
9
10 #include "umpf.h"
11
12 #define DEFAULT_CONF ".umpf"
13
14 void
15 init(void)
16 {
17         signal(SIGPIPE, SIG_IGN);
18         list_init(&input_code);
19         var_hash = new_var_hash();
20         const_tab = xmalloc(BUFSIZE);
21         cur_const_n = 1;
22         cur_const_s = BUFSIZE;
23         empty = "";
24 }
25
26 char* buf;
27 int buflen;
28 char tmpbuf[BUFSIZE];
29 int tmpbufpos;
30 int tmpread;
31
32 char*
33 read_line(int fd)
34 {
35         if (! buflen)
36                 buf = xmalloc(BUFSIZE);
37         char* p = buf;
38         do {
39                 if (tmpbufpos >= tmpread) {
40                         tmpread = read(fd, tmpbuf, BUFSIZE);
41                         tmpbufpos = 0;
42                 }
43                 if (!tmpread)
44                         return NULL;    
45                 if (p >= (buf + buflen - 1))
46                         buf = xrealloc(buf, buflen *= 2);
47                 *p++ = tmpbuf[tmpbufpos++];
48         } while (*p != '\n');
49         *++p = 0; 
50
51         return buf;     
52 }
53
54 char*
55 get_home_from_passwd(void)
56 {
57         struct passwd* pas;
58         pas = getpwuid(getuid());
59         if (! pas)
60                 die("Cannot get uid, please specify config file path");
61
62         char* login = pas->pw_name;
63         int len = strlen(pas->pw_name);
64         char* buf;
65         char* p, *q;
66         int r, i;
67
68         int fd;
69         fd = open("/etc/passwd", O_RDONLY);
70         if (fd < 0)
71                 die("Cannot open /etc/passwd, please specify config file path");
72
73         do {
74                 buf = read_line(fd);
75                 r = strncmp(buf, login, len);
76                 if (!r)
77                         break;
78         } while (buf);
79         if (!r)
80                 die("Cannot find your login %s in /etc/passwd, please specify config file path", login);
81         p = buf;
82         for (i = 0; i < 5; i++) {
83                 p = strchr(p, ':');
84                 if (! p)
85                         die("Cannot parse /etc/passwd, please specify config file path");
86         }       
87         q = p + 1;
88         while (*q && *q != '\n' && *q != ':')
89                 q++;
90         *q = 0;
91         
92         return xstrdup(p + 1);
93 }
94
95 int
96 main(int argc, char** argv)
97 {
98         int res, i, opt;
99         char* conffile = NULL;
100         
101         save_gids();
102         while ((opt = getopt(argc, argv, "c:m:")) != -1) {
103                 switch (opt) {
104                 case 'm':
105                         default_mailbox = optarg;
106                         break;
107                 case 'c':
108                         conffile = optarg;
109                         break;
110                 default:
111                         die("Usage: ./umpf [-c conf_file] [-m default_mailbox]");
112                 }
113         }
114
115         if (!default_mailbox) {
116                 struct passwd* p;
117
118                 p = getpwuid(getuid());
119                 if (! p)
120                         die("Cannot get uid, please specify default mailbox");
121                 default_mailbox = cat("/var/mail/", p->pw_name);
122         }
123
124         init();
125
126         /* returning from longjump? save the mail and exit */
127         if (setjmp(env))
128                 goto skip_conf;
129
130         if (! conffile) {
131                 int len;
132                 char* home; 
133
134                 home = getenv("HOME");
135                 if (! home)
136                         home = get_home_from_passwd();
137                 if (! home)
138                         goto skip_conf;
139
140                 conffile = xmalloc(strlen(home) + strlen(DEFAULT_CONF) + 1);
141                 sprintf(conffile, "%s/%s", home, DEFAULT_CONF); 
142         }
143         read_conf(conffile);
144         res = yyparse ();
145
146         if (res)
147                 return res;
148
149         temp_varcode_start = current_varcode;
150         compile(input_tree, NULL);
151
152 skip_conf:
153         var_tab = xmalloc((max_varcode + 1) * sizeof(struct vartab));
154         for (i = 0; i <= max_varcode; i++) {
155                 var_tab[i].value = empty;
156                 var_tab[i].modif = 0;
157         }       
158
159         current_headers = make_hlist(0);
160         current_body = get_body(0);
161         save_current_headers(var_hash);
162         set_cur_mail_length_var(curr_email_len, var_hash);
163
164         interp(&input_code, var_hash);
165
166         return 0;
167 }