dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / vsftpd / privsock.c
blob17a2cec6759391fcbab89696a30ff1004dbe1088
1 /*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2
4 * Author: Chris Evans
5 * privsock.c
7 * This file contains code for a simple message and file descriptor passing
8 * API, over a pair of UNIX sockets.
9 * The messages are typically travelling across a privilege boundary, with
10 * heavy distrust of messages on the side of more privilege.
13 #include "privsock.h"
15 #include "utility.h"
16 #include "defs.h"
17 #include "str.h"
18 #include "netstr.h"
19 #include "sysutil.h"
20 #include "sysdeputil.h"
21 #include "session.h"
23 void
24 priv_sock_init(struct vsf_session* p_sess)
26 struct vsf_sysutil_socketpair_retval retval;
27 if (p_sess->parent_fd != -1)
29 bug("parent_fd active");
31 if (p_sess->child_fd != -1)
33 bug("child_fd active");
35 retval = vsf_sysutil_unix_stream_socketpair();
36 p_sess->parent_fd = retval.socket_one;
37 p_sess->child_fd = retval.socket_two;
40 void
41 priv_sock_close(struct vsf_session* p_sess)
43 if (p_sess->parent_fd != -1)
45 vsf_sysutil_close(p_sess->parent_fd);
46 p_sess->parent_fd = -1;
48 if (p_sess->child_fd != -1)
50 vsf_sysutil_close(p_sess->child_fd);
51 p_sess->child_fd = -1;
55 void
56 priv_sock_set_parent_context(struct vsf_session* p_sess)
58 if (p_sess->child_fd == -1)
60 bug("child_fd not active");
62 vsf_sysutil_close(p_sess->child_fd);
63 p_sess->child_fd = -1;
66 void
67 priv_sock_set_child_context(struct vsf_session* p_sess)
69 if (p_sess->parent_fd == -1)
71 bug("parent_fd not active");
73 vsf_sysutil_close(p_sess->parent_fd);
74 p_sess->parent_fd = -1;
77 void
78 priv_sock_send_cmd(int fd, char cmd)
80 int retval = vsf_sysutil_write_loop(fd, &cmd, sizeof(cmd));
81 if (retval != sizeof(cmd))
83 die("priv_sock_send_cmd");
87 void
88 priv_sock_send_str(int fd, const struct mystr* p_str)
90 unsigned int len = str_getlen(p_str);
91 priv_sock_send_int(fd, (int) len);
92 if (len > 0)
94 str_netfd_write(p_str, fd);
98 void
99 priv_sock_send_buf(int fd, const char* p_buf, unsigned int len)
101 priv_sock_send_int(fd, (int) len);
102 if (len > 0)
104 if (vsf_sysutil_write_loop(fd, p_buf, len) != (int) len)
106 die("priv_sock_send_buf");
111 void
112 priv_sock_recv_buf(int fd, char* p_buf, unsigned int len)
114 unsigned int recv_len = (unsigned int) priv_sock_get_int(fd);
115 if (recv_len > len)
117 bug("recv_len bigger than buffer");
119 if (recv_len > 0)
121 if (vsf_sysutil_read_loop(fd, p_buf, recv_len) != (int) recv_len)
123 die("priv_sock_recv_buf");
128 char
129 priv_sock_get_result(int fd)
131 char res;
132 int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res));
133 if (retval != sizeof(res))
135 die("priv_sock_get_result");
137 return res;
140 char
141 priv_sock_get_cmd(int fd)
143 char res;
144 int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res));
145 if (retval != sizeof(res))
147 die("priv_sock_get_cmd");
149 return res;
152 void
153 priv_sock_get_str(int fd, struct mystr* p_dest)
155 unsigned int len = (unsigned int) priv_sock_get_int(fd);
156 if (len > VSFTP_PRIVSOCK_MAXSTR)
158 die("priv_sock_get_str: too big");
160 str_empty(p_dest);
161 if (len > 0)
163 int retval = str_netfd_read(p_dest, fd, len);
164 if ((unsigned int) retval != len)
166 die("priv_sock_get_str: read error");
171 void
172 priv_sock_send_result(int fd, char res)
174 int retval = vsf_sysutil_write_loop(fd, &res, sizeof(res));
175 if (retval != sizeof(res))
177 die("priv_sock_send_result");
181 void
182 priv_sock_send_fd(int fd, int send_fd)
184 vsf_sysutil_send_fd(fd, send_fd);
188 priv_sock_recv_fd(int fd)
190 return vsf_sysutil_recv_fd(fd);
193 void
194 priv_sock_send_int(int fd, int the_int)
196 int retval = vsf_sysutil_write_loop(fd, &the_int, sizeof(the_int));
197 if (retval != sizeof(the_int))
199 die("priv_sock_send_int");
204 priv_sock_get_int(int fd)
206 int the_int;
207 int retval = vsf_sysutil_read_loop(fd, &the_int, sizeof(the_int));
208 if (retval != sizeof(the_int))
210 die("priv_sock_get_int");
212 return the_int;