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