append given basedir argument with '/' if not given
[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)
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
50   do {
51     // find next newline, terminate string there
52     for (char* i = self->buffer; i < self->eob; ++i)
53       {
54         if (*i == '\n')
55           {
56             *i = '\0';
57             self->eol = i;
58             // have line, return it
59             return (self->eob == self->buffer) ? NULL : self->buffer;
60           }
61       }
62
63     // else we have to read
64     if (self->state == RXPD_OK)
65       {
66         ssize_t r = 0;
67         do
68           {
69             r = pth_read (fd, self->eob, 4095 - (self->eob - self->buffer));
70           }
71         while (r == -1 && errno == EINTR);
72
73         if (r != -1)
74           {
75             if (r == 0)
76               {
77                 shutdown (fd, SHUT_RD);
78                 self->state = RXPD_EOF;
79               }
80             self->eob += r;
81           }
82         else
83           self->state = RXPD_ERROR;
84       }
85   } while (1);  // TODO while (!buffer overfulls)  
86   return NULL;
87 }
88
89
90 int
91 rxpd_buffer_printf (struct rxpd_buffer* self, const char* fmt, ...)
92 {
93   // for now we do a blocking write, needs to be fixed some day, timeout!
94   va_list ap;
95   va_start(ap, fmt);
96   int n = vsnprintf (self->buffer, 4096, fmt, ap);
97   va_end(ap);
98
99   pth_write (self->conn->fd, self->buffer, n);
100
101   if (n>4095)
102     return 0;
103
104   return 1;
105 }
106
107
108