1 //
2 //	aegis - project change supervisor
3 //	Copyright (C) 2004-2006, 2008 Peter Miller
4 //
5 //	This program is free software; you can redistribute it and/or modify
6 //	it under the terms of the GNU General Public License as published by
7 //	the Free Software Foundation; either version 3 of the License, or
8 //	(at your option) any later version.
9 //
10 //	This program is distributed in the hope that it will be useful,
11 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //	GNU General Public License for more details.
14 //
15 //	You should have received a copy of the GNU General Public License
16 //	along with this program. If not, see
17 //	<http://www.gnu.org/licenses/>.
18 //
19 
20 #ifndef AE_CVS_SERVER_NET_H
21 #define AE_CVS_SERVER_NET_H
22 
23 #include <common/nstring.h>
24 #include <common/str_list.h>
25 #include <libaegis/input.h>
26 #include <libaegis/output.h>
27 
28 #include <aecvsserver/directory.h>
29 
30 enum response_code_ty
31 {
32     response_code_Checked_in,
33     response_code_Checksum,
34     response_code_Clear_static_directory,
35     response_code_Clear_sticky,
36     response_code_Copy_file,
37     response_code_Created,
38     response_code_E,
39     response_code_error,
40     response_code_F,
41     response_code_hate,
42     response_code_love,
43     response_code_M,
44     response_code_Mbinary,
45     response_code_Merged,
46     response_code_Mode,
47     response_code_Mod_time,
48     response_code_Module_expansion,
49     response_code_MT,
50     response_code_New_entry,
51     response_code_Notified,
52     response_code_ok,
53     response_code_Patched,
54     response_code_Rcs_diff,
55     response_code_Removed,
56     response_code_Remove_entry,
57     response_code_Set_checkin_prog,
58     response_code_Set_static_directory,
59     response_code_Set_sticky,
60     response_code_Set_update_prog,
61     response_code_Template,
62     response_code_Updated,
63     response_code_Update_existing,
64     response_code_Valid_requests,
65     response_code_Wrapper_rcsOption,
66     response_code_MAX // must be last
67 };
68 
69 class output_ty; // forward
70 class response; // forward
71 
72 /**
73   * The net_ty class is used to remember the state of a network connection
74   * to a client.
75   */
76 class net_ty
77 {
78 public:
79     /**
80       * The destructor.
81       */
82     virtual ~net_ty();
83 
84     /**
85       * The default constructor.
86       */
87     net_ty();
88 
89     /**
90       * The getline method is used to read one line from the input (up
91       * to the next newline character or end of input).  The newline
92       * is not included in the returned string.  Returns false if
93       * end-of-file is reached.
94       */
95     bool getline(nstring &s);
96 
97     /**
98       * The printf method is used to write output to the client.
99       */
100     void printf(const char *, ...)                            ATTR_PRINTF(2, 3);
101 
102     /**
103       * The response_queue method is used to enqueue a response to be
104       * transmitted at the next response_flush.
105       */
106     void response_queue(response *rp);
107 
108     /**
109       * The response_flush method is used to flush any pending responses
110       * (if any) to the client.
111       */
112     void response_flush(void);
113 
114     /**
115       * The log_to_file method is used to enable logging of all requests
116       * and responses.  This is for debugging.
117       */
118     void log_to_file(string_ty *);
119 
120     /**
121       * The log_by_env method is used to enable logging if the given
122       * environment variable has been set.  The value of the environment
123       * variable is the name of the log file to use.
124       */
125     void log_by_env(const char *);
126 
127     /**
128       * The argument method is used to append the given string to the
129       * argument list.
130       */
131     void argument(string_ty *);
132 
133     /**
134       * The argumentx method is used to append the given string to the
135       * end of the last string on the argument list.
136       */
137     void argumentx(string_ty *);
138 
139     /**
140       * The accumulator_reset method is used to discard the most
141       * recently accumulated lists of directories, entries and arguments.
142       */
143     void accumulator_reset(void);
144 
145     /**
146       * The file_info_find method is used to locate the file info
147       * structure for a particular root-relative file name.
148       *
149       * @param server_side
150       *     The server-side name of the file, including the module name,
151       *     but excluding ROOT_PATH/
152       * @param auto_alloc
153       *     True if the name should be allocated if not foind, false if it
154       *     should not.
155       * @returns
156       *     The corresponding file_info_ty data structure.  Returns NULL if
157       *     auto_alloc was false, and the necessary data was not found.
158       */
159     struct file_info_ty *file_info_find(string_ty *server_side, int auto_alloc);
160 
161     /**
162       * The directory_set method may be used to set the directory,
163       * as given in in a Directory request.
164       */
165     void directory_set(string_ty *cs, string_ty *ss);
166 
167     /**
168       * The directory_find_client_side method is used to search the
169       * existing Directory names, looking for the given client-side directory.
170       * Returns NULL if not found.  Do not free the result.
171       */
172     directory_ty *directory_find_client_side(string_ty *);
173 
174     /**
175       * The directory_find_server_side method is used to search the
176       * existing Directory names, looking for the given server-side directory.
177       * Returns NULL if not found.  Do not free the result.
178       */
179     directory_ty *directory_find_server_side(string_ty *);
180 
181     /**
182       * The get_is_rooted method is used to find out if we have seet a
183       * Root request yet.
184       */
get_is_rooted()185     bool get_is_rooted() const { return rooted; }
186 
187     /**
188       * The set_is_rooted method is used by the Root request to indicate
189       * that a valid Root request has been processed.
190       */
set_is_rooted()191     void set_is_rooted() { rooted = true; }
192 
193     /**
194       * The set_respose_valid method is used the the Valid-Response
195       * request to indicate those responses which are valid for this
196       * client.
197       */
set_response_valid(int n)198     void set_response_valid(int n) { response_valid[n] = true; }
199 
200     /**
201       * The get_updating_verbose method is used to obtain the last
202       * client-side directory we claimed to be updating.
203       */
get_updating_verbose()204     string_ty *get_updating_verbose() const { return updating_verbose; }
205 
206     /**
207       * The get_updating_verbose method is used to set the
208       * client-side directory we are currently updating.
209       */
210     void set_updating_verbose(string_ty *);
211 
212     /**
213       * The in_crop method is used to create a new input source which
214       * reads the next \a length bytes.
215       *
216       * @param length
217       *     The number of bytes to be consumed.
218       * @returns
219       *     an input stream, use it in the usual way.
220       */
221     input in_crop(long length);
222 
get_curdir()223     directory_ty *get_curdir() const { return curdir; }
curdir_is_set()224     bool curdir_is_set() const { return (curdir != 0); }
225 
argument_count()226     size_t argument_count() const { return argument_list.size(); }
argument_nth(size_t n)227     string_ty *argument_nth(size_t n) const { return argument_list[n]; }
228 
229 private:
230     input in;
231     output::pointer out;
232     output::pointer log_client;
233 
234     /**
235       * The rooted instance variable is used to remeber whether we have
236       * seet a Root request yet, or not.
237       */
238     bool rooted;
239 
240     /**
241       * The set of responses which are currently valid.
242       */
243     bool response_valid[response_code_MAX];
244 
245     //
246     // The response queue, the list of responses yet to be sent to
247     // the client.
248     //
249     size_t response_queue_length;
250     size_t response_queue_max;
251     response **response_queue_item;
252 
253     //
254     // The set of directories accumulated by Directory requests until
255     // something eats them all, indexed by client-side path.
256     //
257     struct symtab_ty *dir_info_cs;
258 
259     //
260     // The set of directories accumulated by Directory requests until
261     // something eats them all, indexed by server-side path.
262     //
263     struct symtab_ty *dir_info_ss;
264 
265     //
266     // The most recent Directory request.
267     //
268     directory_ty *curdir;
269 
270     //
271     // The file_info field is used to remember a table of information
272     // about files, indexed by root-relative file name.
273     //
274     struct symtab_ty *file_info;
275 
276     //
277     // The list of strings accumulated by Argument and Argumentx requests
278     // until something eats them all.
279     //
280     string_list_ty argument_list;
281 
282     /**
283       * The updating_verbose instance variable is used to remember the
284       * last client-side directory we claimed to be updating.
285       */
286     string_ty *updating_verbose;
287 
288 private:
289     /**
290       * The copy constructor.  Do not use.
291       */
292     net_ty(const net_ty &);
293 
294     /**
295       * The assignment operator.  Do not use.
296       */
297     net_ty &operator=(const net_ty &);
298 };
299 
300 #endif // AE_CVS_SERVER_NET_H
301