]> mj.ucw.cz Git - eval.git/blob - submit/commands.c
e583d66a518ec97d477cc8afd6b1ce348372f129
[eval.git] / submit / commands.c
1 /*
2  *  The Submit Daemon: High-Level Part of the Protocol
3  *
4  *  (c) 2007 Martin Mares <mj@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/mempool.h"
9 #include "sherlock/object.h"
10 #include "sherlock/objread.h"
11
12 #include "submitd.h"
13
14 /*** REQUESTS AND REPLIES ***/
15
16 static void NONRET
17 read_error_cb(struct obj_read_state *st UNUSED, byte *msg)
18 {
19   client_error("Request parse error: %s", msg);
20 }
21
22 static int
23 read_request(struct conn *c)
24 {
25   if (c->pool)
26     mp_flush(c->pool);
27   else
28     c->pool = mp_new(1024);
29   c->request = obj_new(c->pool);
30   c->reply = obj_new(c->pool);
31
32   struct obj_read_state st;
33   obj_read_start(&st, c->request);
34   st.error_callback = read_error_cb;
35   byte line[1024];
36   uns size = 0;
37   for (;;)
38     {
39       int l = bgets_nodie(&c->rx_fb, line, sizeof(line));
40       if (l < 0)
41         client_error("Request line too long");
42       if (!l)
43         {
44           if (!size)
45             return 0;
46           else
47             client_error("Truncated request");
48         }
49       if (l == 1)
50         break;
51       size += l;
52       if (size >= max_request_size)
53         client_error("Request too long");
54       obj_read_attr(&st, line[0], line+1);
55     }
56   obj_read_end(&st);
57   return 1;
58 }
59
60 static void
61 write_reply(struct conn *c)
62 {
63   if (!obj_find_attr(c->reply, '-') && !obj_find_attr(c->reply, '+'))
64     obj_set_attr(c->reply, '+', "OK");
65   if (trace_commands)
66     {
67       byte *msg;
68       if (msg = obj_find_aval(c->reply, '-'))
69         log(L_DEBUG, ">> -%s", msg);
70       else if (msg = obj_find_aval(c->reply, '+'))
71         log(L_DEBUG, ">> +%s", msg);
72       else
73         log(L_DEBUG, ">> ???");
74     }
75   put_attr_set_type(BUCKET_TYPE_PLAIN);
76   bput_object(&c->tx_fb, c->reply);
77   bputc(&c->tx_fb, '\n');
78   bflush(&c->tx_fb);
79 }
80
81 static void
82 err(struct conn *c, byte *msg)
83 {
84   obj_set_attr(c->reply, '-', msg);
85 }
86
87 /*** SUBMIT ***/
88
89 static void
90 cmd_submit(struct conn *c)
91 {
92   byte *tname = obj_find_aval(c->request, 'T');
93   if (!tname)
94     {
95       err(c, "No task specified");
96       return;
97     }
98   struct task *task = task_find(tname);
99   if (!task)
100     {
101       err(c, "No such task");
102       return;
103     }
104 }
105
106 /*** COMMAND MUX ***/
107
108 static void
109 execute_command(struct conn *c)
110 {
111   byte *cmd = obj_find_aval(c->request, '!');
112   if (!cmd)
113     {
114       err(c, "Missing command");
115       return;
116     }
117   if (trace_commands)
118     log(L_DEBUG, "<< %s", cmd);
119   if (!strcasecmp(cmd, "SUBMIT"))
120     cmd_submit(c);
121   else
122     err(c, "Unknown command");
123 }
124
125 int
126 process_command(struct conn *c)
127 {
128   if (!read_request(c))
129     return 0;
130   execute_command(c);
131   write_reply(c);
132   return 1;
133 }
134
135 /*** INITIAL HANDSHAKE ***/
136
137 static void
138 execute_init(struct conn *c)
139 {
140   byte *user = obj_find_aval(c->request, 'U');
141   if (!user)
142     {
143       err(c, "Missing user");
144       return;
145     }
146   if (!c->cert_name ||
147       !strcmp(user, c->cert_name) ||
148       c->rule->allow_admin && !strcmp(c->cert_name, "admin"))
149     {
150       if (!user_exists_p(user))
151         {
152           err(c, "Unknown user");
153           return;
154         }
155       log(L_INFO, "Logged in %s", user);
156     }
157   else
158     {
159       err(c, "Permission denied");
160       log(L_ERROR, "Unauthorized attempt to log in as %s", user);
161       return;
162     }
163   c->user = xstrdup(user);
164 }
165
166 int
167 process_init(struct conn *c)
168 {
169   if (!read_request(c))
170     return 0;
171   execute_init(c);
172   write_reply(c);
173   return !obj_find_attr(c->reply, '-');
174 }