Setting up a FICS-like server

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
hgm
Posts: 27811
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Setting up a FICS-like server

Post by hgm »

Someone asked me how to set up a FICS-like server, like I have done for the Variant Server on which we have the monthly blitz tourneys. It seemed a good idea todo this in a public place, where people that attempt it could also ask questions and report trouble.

You might want to start by creating a new user "chessd" in your password file, with as home directory /usr/local/chessd, and then log in as this user before you start to install (so that all files you make will have the correct owner). Although it is perfectly possible to install and run the server under your own Linux account.

I use a (slightly modified and debugged) version of the Lasker-2.2.3 code, which runs under Linux. The source code of this can be obtained from my repository at http://hgm.nubati.net/cgi-bin/gitweb.cgi , proect "capablanca.git". After clicking the proect, click the "snapshot" of the latest (= upper most) commit to download a tar ball.

After unpacking the tar ball, you should have a file README, which describes how you have to proceed. You have to go to the "src" directory, and type

./configure--prefix=/usr/local
make
sudo make install

This will install the server in the directory /usr/local/chessd.

Assuming you are in the /usr/local/chessd directory, you can then start the server by the command

bin/chessd -f -p 5000

This will start the server, which will then run as a background process, but will continuously spew output to the console window you started it from, so that it is not advisableto use that for anything else. So open a new terminal window, and use the command

telnet localhost 5000

to connect to the server. You should get the ICS login screen, and you can login as guest using the name "admin" (and type <Enter> or password). This allows you to make an administrator account with "addplayer". (Use "ahelp xxx" to get info on ho to use the administrator command xxx.) You will be told the password, and then should logout, and again login using this password.

That is enough for a first start; first let's see if you can get to thispoint before proceeding.
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

hgm wrote: ./configure --prefix=/usr/local
don't forget space
But i have error when i type make

Code: Select all

chessd@sd-21847&#58;~/src$ make
parsers/genstruct.pl -o parsers/parse_info.h gcc -E -fPIC -Wall -g -O2 -DTDB_STANDALONE  -I. -I./tdb includes.h
Can't use string ("3") as an ARRAY ref while "strict refs" in use at parsers/genstruct.pl line 181.
Parsing enums&#58; netstatusmake&#58; *** &#91;parsers/parse_info.h&#93; Erreur 9
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

Now i have this error when i make

Code: Select all

chessd@sd-21847&#58;~/src$ make
gcc -c -fPIC -Wall -g -O2 -DTDB_STANDALONE  -I. -I./tdb -o parsers/parser.o parsers/parser.c
parsers/parser.c&#58;28&#58; error&#58; expected expression before ‘void’
make&#58; *** &#91;parsers/parser.o&#93; Erreur 1
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

is it correct this file parser.h ?

Code: Select all

/* This is an automatically generated file - DO NOT EDIT! */

static const struct enum_struct einfo_netstatus&#91;&#93; = &#123;

User avatar
hgm
Posts: 27811
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Setting up a FICS-like server

Post by hgm »

Denzwell wrote:But i have error when i type make

Code: Select all

chessd@sd-21847&#58;~/src$ make
parsers/genstruct.pl -o parsers/parse_info.h gcc -E -fPIC -Wall -g -O2 -DTDB_STANDALONE  -I. -I./tdb includes.h
Can't use string ("3") as an ARRAY ref while "strict refs" in use at parsers/genstruct.pl line 181.
Parsing enums&#58; netstatusmake&#58; *** &#91;parsers/parse_info.h&#93; Erreur 9
Hmm, that is a severe setback. I had a similar (or even the same) error when I tried to make on Ubuntu 9.04, preventing me to upgrade. On Ubuntu 8.04 it worked without any errors. (Lots of warnings, though.)

genstruct.pl is a Perl script, not? I know nothing of Perl.

Code: Select all

1 #!/usr/bin/perl -w
2 # a simple system for generating C parse info
3 # this can be used to write generic C structer load/save routines
4 # Copyright 2002 Andrew Tridgell <genstruct@tridgell.net>
5 # released under the GNU General Public License v2 or later
6 
7 use strict;
8 
9 my&#40;%enum_done&#41; = ();
10 my&#40;%struct_done&#41; = ();
11 
12 ###################################################
13 # general handler
14 sub handle_general&#40;$$$$$$$$)
15 &#123;
16         my&#40;$name&#41; = shift;
17         my&#40;$ptr_count&#41; = shift;
18         my&#40;$size&#41; = shift;
19         my&#40;$element&#41; = shift;
20         my&#40;$flags&#41; = shift;
21         my&#40;$dump_fn&#41; = shift;
22         my&#40;$parse_fn&#41; = shift;
23         my&#40;$tflags&#41; = shift;
24         my&#40;$array_len&#41; = 0;
25         my&#40;$dynamic_len&#41; = "NULL";
26 
27         # handle arrays, currently treat multidimensional arrays as 1 dimensional
28         while ($element =~ /(.*)\&#91;(.*?)\&#93;$/) &#123;
29                 $element = $1;
30                 if ($array_len == 0&#41; &#123;
31                         $array_len = $2;
32                 &#125; else &#123;
33                         $array_len = "$2 * $array_len";
34                 &#125;
35         &#125;
36 
37         if ($flags =~ /_LEN\((\w*?)\)/) &#123;
38                 $dynamic_len = ""$1"";
39         &#125;
40 
41         if ($flags =~ /_NULLTERM/) &#123;
42                 $tflags = "FLAG_NULLTERM";
43         &#125;
44 
45         print OFILE "&#123;"$element", $ptr_count, $size, offsetof&#40;struct $name, $element&#41;, $array_len, $dynamic_len, $tflags, $dump_fn, $parse_fn&#125;,\n";
46 &#125;
47 
48 
49 ####################################################
50 # parse one element
51 sub parse_one&#40;$$$$)
52 &#123;
53         my&#40;$name&#41; = shift;
54         my&#40;$type&#41; = shift;
55         my&#40;$element&#41; = shift;
56         my&#40;$flags&#41; = shift;
57         my&#40;$ptr_count&#41; = 0;
58         my&#40;$size&#41; = "sizeof&#40;$type&#41;";
59         my&#40;$tflags&#41; = "0";
60         
61         # enums get the FLAG_ALWAYS flag
62         if ($type =~ /^enum /) &#123;
63                 $tflags = "FLAG_ALWAYS";
64         &#125;
65 
66 
67         # make the pointer part of the base type 
68         while ($element =~ /^\*(.*)/) &#123;
69                 $ptr_count++;
70                 $element = $1;
71         &#125;
72 
73         # convert spaces to _
74         $type =~ s/ /_/g;
75 
76         my&#40;$dump_fn&#41; = "gen_dump_$type";
77         my&#40;$parse_fn&#41; = "gen_parse_$type";
78 
79         handle_general&#40;$name, $ptr_count, $size, $element, $flags, $dump_fn, $parse_fn, $tflags&#41;;
80 &#125;
81 
82 ####################################################
83 # parse one element
84 sub parse_element&#40;$$$)
85 &#123;
86         my&#40;$name&#41; = shift;
87         my&#40;$element&#41; = shift;
88         my&#40;$flags&#41; = shift;
89         my&#40;$type&#41;;
90         my&#40;$data&#41;;
91 
92         # pull the base type
93         if ($element =~ /^struct (\S*) (.*)/) &#123;
94                 $type = "struct $1";
95                 $data = $2;
96         &#125; elsif ($element =~ /^enum (\S*) (.*)/) &#123;
97                 $type = "enum $1";
98                 $data = $2;
99         &#125; elsif ($element =~ /^unsigned (\S*) (.*)/) &#123;
100                 $type = "unsigned $1";
101                 $data = $2;
102         &#125; elsif ($element =~ /^const (\S*) (.*)/) &#123;
103                 $type = $1;
104                 $data = $2;
105         &#125; elsif ($element =~ /^(\S*) (.*)/) &#123;
106                 $type = $1;
107                 $data = $2;
108         &#125; else &#123;
109                 die "Can't parse element '$element'";
110         &#125;
111 
112         # handle comma separated lists 
113         while ($data =~ /(\S*),&#91;\s&#93;?(.*)/) &#123;
114                 parse_one&#40;$name, $type, $1, $flags&#41;;
115                 $data = $2;
116         &#125;
117         parse_one&#40;$name, $type, $data, $flags&#41;;
118 &#125;
119 
120 
121 my&#40;$first_struct&#41; = 1;
122 
123 ####################################################
124 # parse the elements of one structure
125 sub parse_elements&#40;$$)
126 &#123;
127         my&#40;$name&#41; = shift;
128         my&#40;$elements&#41; = shift;
129 
130         if ($first_struct&#41; &#123;
131                 $first_struct = 0;
132                 print "Parsing structs&#58; $name";
133         &#125; else &#123;
134                 print ", $name";
135         &#125;
136 
137         print OFILE "int gen_dump_struct_$name&#40;struct parse_string *, const char *, unsigned&#41;;\n";
138         print OFILE "int gen_parse_struct_$name&#40;char *, const char *);\n";
139 
140         print OFILE "static const struct parse_struct pinfo_" . $name . "&#91;&#93; = &#123;\n";
141 
142         while ($elements =~ /^.*?(&#91;a-z&#93;.*?);\s*?(\S*?)\s*?$(.*)/msi&#41; &#123;
143                 my&#40;$element&#41; = $1;
144                 my&#40;$flags&#41; = $2;
145                 $elements = $3;
146                 parse_element&#40;$name, $element, $flags&#41;;
147         &#125;
148 
149         print OFILE "&#123;NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL&#125;&#125;;\n";
150 
151         print OFILE "
152 int gen_dump_struct_$name&#40;struct parse_string *p, const char *ptr, unsigned indent&#41; &#123;
153         return gen_dump_struct&#40;pinfo_$name, p, ptr, indent&#41;;
154 &#125;
155 int gen_parse_struct_$name&#40;char *ptr, const char *str&#41; &#123;
156         return gen_parse_struct&#40;pinfo_$name, ptr, str&#41;;
157 &#125;
158 
159 ";
160 &#125;
161 
162 my&#40;$first_enum&#41; = 1;
163 
164 ####################################################
165 # parse out the enum declarations
166 sub parse_enum_elements&#40;$$)
167 &#123;
168         my&#40;$name&#41; = shift;
169         my&#40;$elements&#41; = shift;
170 
171         if ($first_enum&#41; &#123;
172                 $first_enum = 0;
173                 print "Parsing enums&#58; $name";
174         &#125; else &#123;
175                 print ", $name";
176         &#125;
177 
178         print OFILE "static const struct enum_struct einfo_" . $name . "&#91;&#93; = &#123;\n";
179 
180         my&#40;@enums&#41; = split&#40;/,/s, $elements&#41;;
181         for &#40;my&#40;$i&#41;=0; $i <= $#&#123;@enums&#125;; $i++) &#123;
182                 my&#40;$enum&#41; = $enums&#91;$i&#93;;
183                 if ($enum =~ /\s*(\w*)/) &#123;
184                         my&#40;$e&#41; = $1;
185                         print OFILE "&#123;"$e", $e&#125;,\n";
186                 &#125;
187         &#125;
188 
189         print OFILE "&#123;NULL, 0&#125;&#125;;\n";
190 
191         print OFILE "
192 int gen_dump_enum_$name&#40;struct parse_string *p, const char *ptr, unsigned indent&#41; &#123;
193         return gen_dump_enum&#40;einfo_$name, p, ptr, indent&#41;;
194 &#125;
195 
196 int gen_parse_enum_$name&#40;char *ptr, const char *str&#41; &#123;
197         return gen_parse_enum&#40;einfo_$name, ptr, str&#41;;
198 &#125;
199 
200 ";
201 &#125;
202 
203 ####################################################
204 # parse out the enum declarations
205 sub parse_enums&#40;$)
206 &#123;
207         my&#40;$data&#41; = shift;
208 
209         while ($data =~ /^GENSTRUCT\s+enum\s+(\w*?)\s*&#123;(.*?)&#125;\s*;(.*)/ms&#41; &#123;
210                 my&#40;$name&#41; = $1;
211                 my&#40;$elements&#41; = $2;
212                 $data = $3;
213 
214                 if (!defined&#40;$enum_done&#123;$name&#125;)) &#123;
215                         $enum_done&#123;$name&#125; = 1;
216                         parse_enum_elements&#40;$name, $elements&#41;;
217                 &#125;
218         &#125;
219 
220         if (! $first_enum&#41; &#123;
221                 print "\n";
222         &#125;
223 &#125;
224 
225 ####################################################
226 # parse all the structures
227 sub parse_structs&#40;$)
228 &#123;
229         my&#40;$data&#41; = shift;
230 
231         # parse into structures 
232         while ($data =~ /^GENSTRUCT\s+struct\s+(\w+?)\s*&#123;\s*(.*?)\s*&#125;\s*;(.*)/ms&#41; &#123;
233                 my&#40;$name&#41; = $1;
234                 my&#40;$elements&#41; = $2;
235                 $data = $3;
236                 if (!defined&#40;$struct_done&#123;$name&#125;)) &#123;
237                         $struct_done&#123;$name&#125; = 1;
238                         parse_elements&#40;$name, $elements&#41;;
239                 &#125;
240         &#125;
241 
242         if (! $first_struct&#41; &#123;
243                 print "\n";
244         &#125; else &#123;
245                 print "No GENSTRUCT structures found?\n";
246         &#125;
247 &#125;
248 
249 
250 ####################################################
251 # parse a header file, generating a dumper structure
252 sub parse_data&#40;$)
253 &#123;
254         my&#40;$data&#41; = shift;
255 
256         # collapse spaces 
257         $data =~ s/&#91;\t &#93;+/ /sg;
258         $data =~ s/\s*\n\s+/\n/sg;
259         # strip debug lines
260         $data =~ s/^\#.*?\n//smg;
261 
262         parse_enums&#40;$data&#41;;
263         parse_structs&#40;$data&#41;;
264 &#125;
265 
266 
267 #########################################
268 # display help text
269 sub ShowHelp&#40;)
270 &#123;
271     print "
272 generator for C structure dumpers
273 Copyright Andrew Tridgell <genstruct\@tridgell.net>
274 
275 Sample usage&#58;
276    genstruct -o output.h gcc -E -O2 -g test.h
277 
278 Options&#58;
279     --help                this help page
280     -o OUTPUT             place output in OUTPUT
281 ";
282     exit&#40;0&#41;;
283 &#125;
284 
285 ########################################
286 # main program
287 if ($ARGV&#91;0&#93; ne "-o" || $#ARGV < 2&#41; &#123;
288         ShowHelp&#40;);
289 &#125;
290 
291 shift;
292 my&#40;$opt_ofile&#41;=shift;
293 
294 open&#40;OFILE, ">$opt_ofile") || die "can't open $opt_ofile";    
295 
296 print OFILE "/* This is an automatically generated file - DO NOT EDIT! */\n\n";
297 
298 parse_data&#40;`@ARGV -DGENSTRUCT=GENSTRUCT`);
299 exit&#40;0&#41;;
Is there a Perl expert here that could tell us what the problem with line 181 is?
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

is it correct this file parser_info.h ?

Code: Select all

/* This is an automatically generated file - DO NOT EDIT! */

static const struct enum_struct einfo_netstatus&#91;&#93; = &#123;

my errors

Code: Select all

 make
gcc -c -fPIC -Wall -g -O2 -DTDB_STANDALONE  -I. -I./tdb -o parsers/parser.o parsers/parser.c
parsers/parser.c&#58;28&#58; error&#58; expected expression before ‘void’
make&#58; *** &#91;parsers/parser.o&#93; Erreur 1
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

Perl problem is now ok .

But parser.c calls parse_info.h and i think this file is not correct
User avatar
hgm
Posts: 27811
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Setting up a FICS-like server

Post by hgm »

Well, as parser-info.h is generated by the Perl script that produced the error above, I would not be surprised if it is corrupted.

As to the error you get in compiling parser.c:

Code: Select all

19 /*
20   automatic marshalling/unmarshalling system for C structures
21 */
22 
23 #define EXTERN
24 #include "includes.h"
25 #include "parsers/parse_info.h"
26 
27 /* load all the globals */
28 void load_all_globals&#40;const char *fname&#41;
29 &#123;
...
This occurs at the beginning of line 28, which is immediately after the inclusion of parser_info.h. So it is likely that parser_info.h is incompletely generated, because the Perl script generating it aborted due to the error, and ends half-way in some C construct.

PerhapsI should check out how parser_info.h is supposed to look when I get no error message,and compare it to what you get. For that, however, I have to first boot up Linux.
Denzwell
Posts: 40
Joined: Fri Mar 05, 2010 2:22 pm

Re: Setting up a FICS-like server

Post by Denzwell »

hgm wrote:Well, as parser-info.h is generated by the Perl script that produced the error above, I would not be surprised if it is corrupted.

As to the error you get in compiling parser.c:

Code: Select all

19 /*
20   automatic marshalling/unmarshalling system for C structures
21 */
22 
23 #define EXTERN
24 #include "includes.h"
25 #include "parsers/parse_info.h"
26 
27 /* load all the globals */
28 void load_all_globals&#40;const char *fname&#41;
29 &#123;
...
This occurs at the beginning of line 28, which is immediately after the inclusion of parser_info.h. So it is likely that parser_info.h is incompletely generated, because the Perl script generating it aborted due to the error, and ends half-way in some C construct.

PerhapsI should check out how parser_info.h is supposed to look when I get no error message,and compare it to what you get. For that, however, I have to first boot up Linux.
Yes i am sur that the file parser_info.h is incompletely generated

I created a user cheessd, i can give you by private message his password and my server ip
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Setting up a FICS-like server

Post by Sven »

As to the perl script, line 181 is correct Perl so you may assume that the function around that line gets some bad input. The input is generated by the "gcc ..." command that is passed to genstruct.pl on the command line, as can be seen in genstruct.pl line 298:

Code: Select all

parse_data&#40;`@ARGV -DGENSTRUCT=GENSTRUCT`);
So calling "parsers/genstruct.pl -o parsers/parse_info.h gcc -E -fPIC -Wall -g -O2 -DTDB_STANDALONE -I. -I./tdb includes.h" leads to this:

Code: Select all

gcc -E -fPIC -Wall -g -O2 -DTDB_STANDALONE  -I. -I./tdb includes.h -DGENSTRUCT=GENSTRUCT
and the standard output of this command (in this case, the C preprocessor output since option -E is used) is passed as a long string to the "parse_data()" script function. This makes clear why results can vary between different systems: nobody guarantees that calling "gcc" will always produce exactly the same standard output.

If the original problem (incomplete generation of parse_info.h, probably due to some error popping up in line 181) persists then I would propose to compare the output of the "gcc ..." command line on different systems.

Sven