factored the source into smaller files covering single functionality
[rxpd] / src / rxpd_buffer.c
1 /*
2     rxpd_buffer.c - regex policy daemon
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "rxpd.h"
23
24 struct rxpd_buffer*
25 rxpd_buffer_init (struct rxpd_buffer* self, struct rxpd_connection* conn)
26 {
27   self->conn = conn;
28   self->state = RXPD_OK;
29   self->eol = self->eob = self->buffer;
30   self->buffer [4095] = '\0';
31   return self;
32 }
33
34
35 char*
36 rxpd_buffer_readline (struct rxpd_buffer* self, int again)
37 {
38   int fd = self->conn->fd;
39
40   if (self->eol < self->eob)
41     {
42       //there was a line pending, shift buffer left
43       memmove (self->buffer, self->eol+1, self->eob - self->eol - 1);
44       self->eob = (char*)(self->eob - (self->eol - self->buffer + 1));
45       self->eol = self->buffer;
46       // TODO handle \r's
47     }
48
49   if (!again && self->state == RXPD_OK)   // we only read when again is 0, first iteration
50     {
51       ssize_t r = 0;
52       do
53         {
54           r = read(fd, self->eob, 4095 - (self->eob - self->buffer));
55         }
56       while (r == -1 && errno == EINTR);
57
58       if (r != -1)
59         {
60
61           if (r == 0)
62             {
63               shutdown (fd, SHUT_RD);
64               self->state = RXPD_EOF;
65             }
66
67           self->eob += r;
68         }
69       else
70         self->state = RXPD_ERROR;
71     }
72
73   // find next newline, terminate string there
74   for (char* i = self->buffer; i < self->eob; ++i)
75     {
76       if (*i == '\n')
77         {
78           *i = '\0';
79           self->eol = i;
80           break;
81         }
82     }
83
84   // TODO handle buffer overfulls
85
86   return (self->eob == self->buffer) ? NULL : self->buffer;
87 }
88
89 /*
90 void
91 rxpd_buffer_write(int fd, short event, void* ptr)
92 {
93   struct rxpd_buffer* self = (struct rxpd_buffer*) ptr;
94
95   ssize_t n = write(int fd, const void *buf, size_t count);
96
97 }
98 */
99
100 int
101 rxpd_buffer_printf (struct rxpd_buffer* self, const char* fmt, ...)
102 {
103   // for now we do a blocking write, needs to be fixed some day
104   va_list ap;
105   va_start(ap, fmt);
106   int n = vsnprintf (self->buffer, 4096, fmt, ap);
107   va_end(ap);
108
109   write (self->conn->fd, self->buffer, n);
110
111   if (n>4095)
112     return 0;
113
114   return 1;
115 }
116
117
118