1 #line 1 "wzd_cookie_lex.l"
2 /* vi:ai:et:ts=8 sw=2
3  */
4 /*
5  * wzdftpd - a modular and cool ftp server
6  * Copyright (C) 2002-2003  Pierre Chifflier
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * As a special exemption, Pierre Chifflier
23  * and other respective copyright holders give permission to link this program
24  * with OpenSSL, and distribute the resulting executable, without including
25  * the source code for OpenSSL in the source distribution.
26  */
27 /** \file wzd_cookie_lex.l
28  * \brief Cookie parser
29  * \bug Flex is NOT reentrant by default
30  */
31 %x sc_buf
32 %x sc_cook
33 
34 %{
35 #if defined(WIN32)
36 #include <winsock2.h>
37 #ifdef __CYGWIN__
38 #include <w32api/ws2tcpip.h>
39 #endif
40 
41 #else
42 
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 
48 #include <netdb.h> /* gethostbyaddr */
49 
50 #endif /* __CYGWIN__ && WINSOCK_SUPPORT */
51 
52 #ifdef HAVE_LIMITS_H
53 # include <limits.h>
54 #endif
55 
56 #ifndef WIN32
57 # include <sys/types.h>
58 # include <sys/ipc.h>
59 # include <sys/shm.h>
60 #endif /* WIN32 */
61 
62 #include <stdio.h>
63 #include <string.h>
64 #include <time.h>
65 #include <sys/stat.h>
66 #include <errno.h>
67 #include <fcntl.h>
68 #include <ctype.h>
69 
70 #include "wzd_structs.h"
71 #include "wzd_log.h"
72 #include "wzd_misc.h"
73 
74 #include "wzd_cache.h"
75 #include "wzd_crc32.h"
76 #include "wzd_group.h"
77 #include "wzd_ip.h"
78 #include "wzd_messages.h"
79 #include "wzd_section.h"
80 #include "wzd_user.h"
81 #include "wzd_vfs.h"
82 
83 #include "wzd_debug.h"
84 #include "wzd_libmain.h"
85 
86 typedef enum {
87   COOKIE=257,
88   COOKIE_EOL,
89   COOKIE_FOR,
90   COOKIE_ENDFOR,
91   COOKIE_IF,
92   COOKIE_ENDIF,
93 
94   COOKIE_INCLUDE,
95 
96   COOKIE_INVALID,
97 
98   COOKIE_NOCOL,
99   COOKIE_BLACK,
100   COOKIE_RED,
101   COOKIE_GREEN,
102   COOKIE_BROWN,
103   COOKIE_BLUE,
104   COOKIE_MAGENTA,
105   COOKIE_CYAN,
106   COOKIE_WHITE,
107 
108   COOKIE_NEWLINE,
109 
110   COOKIE_CONNECTED_MAX,
111   COOKIE_CONNECTED_USERS,
112 
113   COOKIE_TOTAL_DL,
114   COOKIE_TOTAL_DL2,
115   COOKIE_TOTAL_UL,
116   COOKIE_TOTAL_UL2,
117 
118   COOKIE_FILECRC,
119   COOKIE_FILEPATH,
120 
121   COOKIE_GROUPHOME,
122   COOKIE_GROUPID,
123   COOKIE_GROUPIP_ALLOW,
124   COOKIE_GROUPMAXDL,
125   COOKIE_GROUPMAXIDLE,
126   COOKIE_GROUPMAXUL,
127   COOKIE_GROUPNAME,
128   COOKIE_GROUPNUM_LOGINS,
129   COOKIE_GROUPRATIO,
130   COOKIE_GROUPTAG,
131   COOKIE_GROUPTOTAL_DL,
132   COOKIE_GROUPTOTAL_DL2,
133   COOKIE_GROUPTOTAL_UL,
134   COOKIE_GROUPTOTAL_UL2,
135 
136   COOKIE_LASTFILECRC,
137   COOKIE_LASTFILENAME,
138   COOKIE_LASTFILESIZE,
139   COOKIE_LASTFILESPEED,
140   COOKIE_LASTFILETIME,
141 
142   COOKIE_MSG,
143 
144   COOKIE_SECTIONNAME,
145 
146   COOKIE_SPACEFREE,
147   COOKIE_SPACETOTAL,
148 
149   COOKIE_USERCREDITS,
150   COOKIE_USERCREDITS2,
151   COOKIE_USERFILES_DL,
152   COOKIE_USERFILES_UL,
153   COOKIE_USERFLAGS,
154   COOKIE_USERGROUP,
155   COOKIE_USERGROUPS,
156   COOKIE_USERHOME,
157   COOKIE_USERID,
158   COOKIE_USERIP,
159   COOKIE_USERIP_ALLOW,
160   COOKIE_USERLASTCMD,
161   COOKIE_USERLAST_LOGIN,
162   COOKIE_USERLEECHSLOTS,
163   COOKIE_USERMAXDL,
164   COOKIE_USERMAXIDLE,
165   COOKIE_USERMAXUL,
166   COOKIE_USERNAME,
167   COOKIE_USERNUM_LOGINS,
168   COOKIE_USERPATH,
169   COOKIE_USERPID,
170   COOKIE_USERPWD,
171   COOKIE_USERRATIO,
172   COOKIE_USERSLOTS,
173   COOKIE_USERSPEED,
174   COOKIE_USERTAG,
175   COOKIE_USERTIME,
176   COOKIE_USERTOTAL_DL,
177   COOKIE_USERTOTAL_DL2,
178   COOKIE_USERTOTAL_UL,
179   COOKIE_USERTOTAL_UL2,
180 
181   COOKIE_VFSVIRTUAL,
182   COOKIE_VFSPHYSICAL,
183   COOKIE_VFSTARGET,
184 } sc_cookie_t;
185 
186 /* this var defines a 'prefered' minimal buffer size before sending */
187 #define MIN_SEND_BUFFERSIZE	500
188 #define MAX_SEND_BUFFERSIZE	4096
189 
190 #define MAX_LOOP_DEPTH	10
191 char * loop_buffer[MAX_LOOP_DEPTH];
192 int loop_buffer_type[MAX_LOOP_DEPTH];
193 int loop_buffer_ptr=0;
194 
195 #define MAX_INCLUDE_DEPTH 10
196 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
197 int cookie_include_stack_ptr = 0;
198 
199 #define IBUFSIZE	4096
200 
201 wzd_user_t * current_user=NULL;
202 wzd_group_t * current_group=NULL;
203 wzd_context_t * current_context=NULL;
204 wzd_vfs_t * current_vfs=NULL;
205 
206 static int cookie_parse_buffer_r(const char *buffer, wzd_user_t * user, wzd_group_t * group,
207   wzd_context_t * context, char * out_buffer, unsigned int out_buffer_len);
208 %}
209 
210 DIGIT [0-9]
211 LETTER  [a-zA-Z]
212 
213 LF		\x0A
214 CR		\x0D
215 NL		{CR}*{LF}
216 
217 FOR_BEGIN	"%for("{LETTER}+")"{NL}
218 FOR_END		"%endfor"{NL}
219 
220 IF_BEGIN	"%if("("+"|"=")?{LETTER}+")"{NL}
221 IF_END		"%endif"{NL}
222 
223 C_START		"%"
224 C_BW		([0-9]+".")?"bw"
225 C_CONN		([0-9]+".")?"connected_"
226 C_FILE		([0-9]+".")?"file"
227 C_GROUP		([0-9]+".")?"group"
228 C_LASTFILE	([0-9]+".")?"lastfile"
229 C_USER		([0-9]+".")?"user"
230 C_VFS    ([0-9]+".")?"vfs"
231 
232 %option nounput
233 %option noyywrap
234 /*%option debug*/
235 %option never-interactive
236 %option prefix="cookie"
237 %option outfile="lex.yy.c"
238 %%
239 
240 <INITIAL>\r		/* ignore */
241 <INITIAL>\n		return COOKIE_EOL;
242 
243 <INITIAL>{FOR_BEGIN}	{
244   BEGIN(sc_buf);
245   if (loop_buffer_ptr >= MAX_LOOP_DEPTH){
246 #ifdef WZD_DBG_COOKIES
247     out_err(LEVEL_HIGH, "Loops nested too deeply\n" );
248 #endif
249     return 0;
250   }
251   loop_buffer_type[loop_buffer_ptr++] = COOKIE_FOR;
252   return COOKIE_FOR;
253 }
254 <INITIAL>{IF_BEGIN}	{
255   BEGIN(sc_buf);
256   if (loop_buffer_ptr >= MAX_LOOP_DEPTH){
257 #ifdef WZD_DBG_COOKIES
258     out_err(LEVEL_HIGH, "Loops nested too deeply\n" );
259 #endif
260     return 0;
261   }
262   loop_buffer_type[loop_buffer_ptr++] = COOKIE_IF;
263   return COOKIE_IF;
264 }
265 
266 <INITIAL>{FOR_END}	return COOKIE_ENDFOR;
267 <INITIAL>{IF_END}	return COOKIE_ENDIF;
268 
269 <sc_buf>{FOR_BEGIN}	{
270   if (loop_buffer_ptr >= MAX_LOOP_DEPTH){
271 #ifdef WZD_DBG_COOKIES
272     out_err(LEVEL_HIGH, "Loops nested too deeply\n" );
273 #endif
274     return 0;
275   }
276   loop_buffer_type[loop_buffer_ptr++] = COOKIE_FOR;
277   return COOKIE_FOR;
278 }
279 <sc_buf>{FOR_END}	{
280   --loop_buffer_ptr;
281   if (loop_buffer_type[loop_buffer_ptr] != COOKIE_FOR) {
282 #ifdef WZD_DBG_COOKIES
283     out_err(LEVEL_HIGH, "Unexpected %%endfor\n" );
284 #endif
285     return 0;
286   }
287   if (loop_buffer_ptr)
288     return *yytext;
289   else
290     return COOKIE_ENDFOR;
291 }
292 <sc_buf>{IF_BEGIN}	{
293   if (loop_buffer_ptr >= MAX_LOOP_DEPTH){
294 #ifdef WZD_DBG_COOKIES
295     out_err(LEVEL_HIGH, "Loops nested too deeply\n" );
296 #endif
297     return 0;
298   }
299   loop_buffer_type[loop_buffer_ptr++] = COOKIE_IF;
300   return COOKIE_IF;
301 }
302 <sc_buf>{IF_END}	{
303   --loop_buffer_ptr;
304   if (loop_buffer_type[loop_buffer_ptr] != COOKIE_IF) {
305 #ifdef WZD_DBG_COOKIES
306     out_err(LEVEL_HIGH, "Unexpected %%endif\n" );
307 #endif
308     return 0;
309   }
310   if (loop_buffer_ptr)
311     return *yytext;
312   else
313     return COOKIE_ENDIF;
314 }
315 
316 <sc_buf>%	return '%';
317 <sc_buf>([^%]|[ \r\n])*	return *yytext;
318 
319 {C_START}	BEGIN(sc_cook);
320 <sc_cook>%	BEGIN(INITIAL); return '%';
321 <sc_cook>!0	BEGIN(INITIAL); return COOKIE_NOCOL;
322 <sc_cook>!black	BEGIN(INITIAL); return COOKIE_BLACK;
323 <sc_cook>!red	BEGIN(INITIAL); return COOKIE_RED;
324 <sc_cook>!green	BEGIN(INITIAL); return COOKIE_GREEN;
325 <sc_cook>!brown	BEGIN(INITIAL); return COOKIE_BROWN;
326 <sc_cook>!blue	BEGIN(INITIAL); return COOKIE_BLUE;
327 <sc_cook>!magenta	BEGIN(INITIAL); return COOKIE_MAGENTA;
328 <sc_cook>!cyan	BEGIN(INITIAL); return COOKIE_CYAN;
329 <sc_cook>!white	BEGIN(INITIAL); return COOKIE_WHITE;
330 
331 <sc_cook>{C_BW}total_dl2	BEGIN(INITIAL); return COOKIE_TOTAL_DL2;
332 <sc_cook>{C_BW}total_dl		BEGIN(INITIAL); return COOKIE_TOTAL_DL;
333 <sc_cook>{C_BW}total_ul2	BEGIN(INITIAL); return COOKIE_TOTAL_UL2;
334 <sc_cook>{C_BW}total_ul		BEGIN(INITIAL); return COOKIE_TOTAL_UL;
335 
336 <sc_cook>{C_CONN}maxusers	BEGIN(INITIAL); return COOKIE_CONNECTED_MAX;
337 <sc_cook>{C_CONN}users		BEGIN(INITIAL); return COOKIE_CONNECTED_USERS;
338 
339 <sc_cook>{C_FILE}crc		BEGIN(INITIAL); return COOKIE_FILECRC;
340 <sc_cook>{C_FILE}path		BEGIN(INITIAL); return COOKIE_FILEPATH;
341 
342 <sc_cook>{C_GROUP}home		BEGIN(INITIAL); return COOKIE_GROUPHOME;
343 <sc_cook>{C_GROUP}id		BEGIN(INITIAL); return COOKIE_GROUPID;
344 <sc_cook>{C_GROUP}ip_allow[0-9]+	BEGIN(INITIAL); return COOKIE_GROUPIP_ALLOW;
345 <sc_cook>{C_GROUP}maxdl		BEGIN(INITIAL); return COOKIE_GROUPMAXDL;
346 <sc_cook>{C_GROUP}maxidle	BEGIN(INITIAL); return COOKIE_GROUPMAXIDLE;
347 <sc_cook>{C_GROUP}maxul		BEGIN(INITIAL); return COOKIE_GROUPMAXUL;
348 <sc_cook>{C_GROUP}name		BEGIN(INITIAL); return COOKIE_GROUPNAME;
349 <sc_cook>{C_GROUP}num_logins	BEGIN(INITIAL); return COOKIE_GROUPNUM_LOGINS;
350 <sc_cook>{C_GROUP}ratio		BEGIN(INITIAL); return COOKIE_GROUPRATIO;
351 <sc_cook>{C_GROUP}tag		BEGIN(INITIAL); return COOKIE_GROUPTAG;
352 <sc_cook>{C_GROUP}total_dl2	BEGIN(INITIAL); return COOKIE_GROUPTOTAL_DL2;
353 <sc_cook>{C_GROUP}total_dl	BEGIN(INITIAL); return COOKIE_GROUPTOTAL_DL;
354 <sc_cook>{C_GROUP}total_ul2	BEGIN(INITIAL); return COOKIE_GROUPTOTAL_UL2;
355 <sc_cook>{C_GROUP}total_ul	BEGIN(INITIAL); return COOKIE_GROUPTOTAL_UL;
356 
357 <sc_cook>{C_LASTFILE}crc	BEGIN(INITIAL); return COOKIE_LASTFILECRC;
358 <sc_cook>{C_LASTFILE}name	BEGIN(INITIAL); return COOKIE_LASTFILENAME;
359 <sc_cook>{C_LASTFILE}size	BEGIN(INITIAL); return COOKIE_LASTFILESIZE;
360 <sc_cook>{C_LASTFILE}speed	BEGIN(INITIAL); return COOKIE_LASTFILESPEED;
361 <sc_cook>{C_LASTFILE}time	BEGIN(INITIAL); return COOKIE_LASTFILETIME;
362 
363 <sc_cook>msg                    BEGIN(INITIAL); return COOKIE_MSG;
364 
365 <sc_cook>sectionname            BEGIN(INITIAL); return COOKIE_SECTIONNAME;
366 <sc_cook>spacefree              BEGIN(INITIAL); return COOKIE_SPACEFREE;
367 <sc_cook>spacetotal             BEGIN(INITIAL); return COOKIE_SPACETOTAL;
368 
369 <sc_cook>{C_USER}credits2	BEGIN(INITIAL); return COOKIE_USERCREDITS2;
370 <sc_cook>{C_USER}credits	BEGIN(INITIAL); return COOKIE_USERCREDITS;
371 <sc_cook>{C_USER}files_dl	BEGIN(INITIAL); return COOKIE_USERFILES_DL;
372 <sc_cook>{C_USER}files_ul	BEGIN(INITIAL); return COOKIE_USERFILES_UL;
373 <sc_cook>{C_USER}flags		BEGIN(INITIAL); return COOKIE_USERFLAGS;
374 <sc_cook>{C_USER}groups		BEGIN(INITIAL); return COOKIE_USERGROUPS;
375 <sc_cook>{C_USER}group		BEGIN(INITIAL); return COOKIE_USERGROUP;
376 <sc_cook>{C_USER}home		BEGIN(INITIAL); return COOKIE_USERHOME;
377 <sc_cook>{C_USER}id		BEGIN(INITIAL); return COOKIE_USERID;
378 <sc_cook>{C_USER}ip_allow[0-9]+	BEGIN(INITIAL); return COOKIE_USERIP_ALLOW;
379 <sc_cook>{C_USER}ip		BEGIN(INITIAL); return COOKIE_USERIP;
380 <sc_cook>{C_USER}lastcmd	BEGIN(INITIAL); return COOKIE_USERLASTCMD;
381 <sc_cook>{C_USER}last_login	BEGIN(INITIAL); return COOKIE_USERLAST_LOGIN;
382 <sc_cook>{C_USER}leechslots	BEGIN(INITIAL); return COOKIE_USERLEECHSLOTS;
383 <sc_cook>{C_USER}maxdl		BEGIN(INITIAL); return COOKIE_USERMAXDL;
384 <sc_cook>{C_USER}maxidle	BEGIN(INITIAL); return COOKIE_USERMAXIDLE;
385 <sc_cook>{C_USER}maxul		BEGIN(INITIAL); return COOKIE_USERMAXUL;
386 <sc_cook>{C_USER}name		BEGIN(INITIAL); return COOKIE_USERNAME;
387 <sc_cook>{C_USER}num_logins	BEGIN(INITIAL); return COOKIE_USERNUM_LOGINS;
388 <sc_cook>{C_USER}path		BEGIN(INITIAL); return COOKIE_USERPATH;
389 <sc_cook>{C_USER}pid		BEGIN(INITIAL); return COOKIE_USERPID;
390 <sc_cook>{C_USER}pwd		BEGIN(INITIAL); return COOKIE_USERPWD;
391 <sc_cook>{C_USER}ratio		BEGIN(INITIAL); return COOKIE_USERRATIO;
392 <sc_cook>{C_USER}slots		BEGIN(INITIAL); return COOKIE_USERSLOTS;
393 <sc_cook>{C_USER}speed		BEGIN(INITIAL); return COOKIE_USERSPEED;
394 <sc_cook>{C_USER}tag		BEGIN(INITIAL); return COOKIE_USERTAG;
395 <sc_cook>{C_USER}time		BEGIN(INITIAL); return COOKIE_USERTIME;
396 <sc_cook>{C_USER}total_dl2	BEGIN(INITIAL); return COOKIE_USERTOTAL_DL2;
397 <sc_cook>{C_USER}total_dl	BEGIN(INITIAL); return COOKIE_USERTOTAL_DL;
398 <sc_cook>{C_USER}total_ul2	BEGIN(INITIAL); return COOKIE_USERTOTAL_UL2;
399 <sc_cook>{C_USER}total_ul	BEGIN(INITIAL); return COOKIE_USERTOTAL_UL;
400 <sc_cook>{C_VFS}virtual  BEGIN(INITIAL); return COOKIE_VFSVIRTUAL;
401 <sc_cook>{C_VFS}physical  BEGIN(INITIAL); return COOKIE_VFSPHYSICAL;
402 <sc_cook>{C_VFS}target  BEGIN(INITIAL); return COOKIE_VFSTARGET;
403 
404 <sc_cook>include         BEGIN(INITIAL); return COOKIE_INCLUDE;
405 
406 <sc_cook>.	BEGIN(INITIAL); return COOKIE_INVALID;
407 
408 .		return *yytext;
409 
410 %%
411 
412 void get_cookie_format(const char *cookie, int * padding)
413 {
414   unsigned long l;
415   char *ptr;
416 
417   *padding = 0;
418 
419   l=strtoul(cookie,&ptr,10);
420   if (*ptr == '.') { /* test should have been done by lexical analyser */
421     if (l <= 5000) /* FIXME hardcoded limit */
422       *padding = l;
423   }
424 }
425 
cookie_parse_buffer(const char * buffer,wzd_user_t * user,wzd_group_t * group,wzd_context_t * context,char * out_buffer,unsigned int out_buffer_len)426 int cookie_parse_buffer(const char *buffer, wzd_user_t * user, wzd_group_t * group,
427 wzd_context_t * context, char * out_buffer, unsigned int out_buffer_len)
428 {
429   int ret;
430 
431   WZD_MUTEX_LOCK(SET_MUTEX_COOKIE_PARSER);
432   ret = cookie_parse_buffer_r(buffer,user,group,context,out_buffer,out_buffer_len);
433   WZD_MUTEX_UNLOCK(SET_MUTEX_COOKIE_PARSER);
434 
435   return ret;
436 }
437 
cookie_parse_buffer_r(const char * buffer,wzd_user_t * user,wzd_group_t * group,wzd_context_t * context,char * out_buffer,unsigned int out_buffer_len)438 static int cookie_parse_buffer_r(const char *buffer, wzd_user_t * user, wzd_group_t * group,
439 wzd_context_t * context, char * out_buffer, unsigned int out_buffer_len)
440 {
441   wzd_user_t * me = NULL;
442   char send_buffer[MAX_SEND_BUFFERSIZE];
443   char internalbuffer[IBUFSIZE];
444   char condition[256];
445   unsigned int length;
446   unsigned int cookie;
447   int i, padding;
448   char * cookie_ptr = NULL;
449   int cookie_length;
450   int convert=0;
451   float val;
452   char c;
453   u64_t total;
454   unsigned int send_buffer_ptr=0;
455   unsigned short use_colors=0;
456   char * out_buffer_ptr;
457   wzd_context_t * real_context;
458   wzd_context_t * loop_context;
459   ListElmt * elmnt;
460 
461 if (!buffer) return -1;
462 /*  if (!context) return -1;*/ /* XXX this prevent using the function from cron jobs ! */
463   real_context = GetMyContext();
464 /*  if (!real_context) return -1;*/ /* XXX this prevent using the function from cron jobs ! */
465   if (real_context)
466     me = GetUserByID(real_context->userid);
467 /*  if (!me) return -1;*/
468 
469   if (me && me->flags && strchr(me->flags,FLAG_COLOR)) use_colors=1;
470 
471   if ( cookie_include_stack_ptr >= MAX_INCLUDE_DEPTH )
472   {
473 #ifdef WZD_DBG_COOKIES
474     out_err(LEVEL_HIGH, "Includes nested too deeply" );
475 #endif
476     return -1;
477   }
478 
479   if (cookie_include_stack_ptr)
480     include_stack[cookie_include_stack_ptr] = YY_CURRENT_BUFFER;
481   cookie_include_stack_ptr++;
482   yy_switch_to_buffer(yy_scan_string(buffer));
483 
484   current_context = context;
485   current_user = user;
486   current_group = group;
487 
488   if (out_buffer) *out_buffer = '\0';
489   out_buffer_ptr = out_buffer;
490 
491   while ( (cookie=yylex()) )
492   {
493     cookie_ptr = NULL;
494     cookie_length = 0;
495     padding = 0;
496     switch(cookie) {
497     case COOKIE_IF:
498     {
499       char * tmpbuf;
500       chop(yytext);
501       length = strlen(yytext);
502       if (length<5 || length>=256)
503       {
504 #ifdef WZD_DBG_COOKIES
505         out_err(LEVEL_HIGH, "Invalid if loop\n" );
506 #endif
507         return 1;
508       }
509       memcpy(condition,yytext+4,length-5); /* 5 = strlen("%if()"= */
510       condition[length-5]='\0';
511       i=0;
512       tmpbuf = malloc(16384);
513 #if 0
514 out_err(LEVEL_HIGH,"AAAAAAAAAAAAAAAA\n");
515       {
516         char c;
517         while ( (c= input()) && c != EOF && (c == '\r' || c == '\n'))
518         {
519 out_err(LEVEL_HIGH,"char: %d [%c]\n", c, c);
520           /* eat EOL */
521         }
522       }
523 #endif
524 /*      printf("starting if loop (%s)\n",condition);*/
525       while ((cookie=yylex()) && cookie!=COOKIE_ENDIF)
526       {
527         /*	if (i>=LOOP_MAX_LINES) {
528                 printf("too much lines in for loop (max %d\n)",LOOP_MAX_LINES);
529                 return 1;
530                 }*/
531         while (yytext[0] && (yytext[0] == '\r' || yytext[0] == '\n')) yytext++;
532         if ( (i+strlen(yytext)) >= 16384 ) {
533 #ifdef WZD_DBG_COOKIES
534           out_err(LEVEL_HIGH, "loop TOO LONG !\n" );
535 #endif
536           exit(1);
537         }
538         strcpy(tmpbuf+i,yytext);
539 /*        printf("%sMARK\n",yytext);*/
540         i+=strlen(yytext);
541       }
542       if (cookie) {
543 /*        printf("End of if loop (i=%d)\n",i);*/
544         BEGIN(INITIAL);
545       } else {
546 #ifdef WZD_DBG_COOKIES
547         out_err(LEVEL_HIGH, "unterminated if loop\n" );
548 #endif
549         free(tmpbuf);
550         return 1;
551       }
552       /* flush buffer before executing 'for' loop */
553 /*      printf("flushing buffer on IF\n");*/
554       /* flush buffer */
555       if (out_buffer) {
556         unsigned int l = send_buffer_ptr;
557         if (l >= out_buffer_len) {
558 #ifdef WZD_DBG_COOKIES
559           out_err(LEVEL_HIGH,"buffer truncated !");
560 #endif
561           l = out_buffer_len - 1;
562         }
563         memcpy(out_buffer_ptr,send_buffer,l);
564         out_buffer_ptr[l] = '\0';
565         out_buffer_ptr += l;
566       } else {
567         send_buffer[send_buffer_ptr]='\0';
568         if (real_context)
569           send_message_raw(send_buffer,real_context);
570         send_buffer_ptr=0;
571       }
572       /* test if() condition */
573       /* TODO XXX FIXME more checks needed ! */
574       if (condition[0] == '+') {
575         WZD_ASSERT( (current_user != NULL) );
576         if (current_user && current_user->flags && strchr(user->flags,condition[1]))
577           cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
578       }
579       free(tmpbuf);
580     }
581     break;
582     case COOKIE_FOR:
583     {
584       char * tmpbuf;
585       chop(yytext);
586       length = strlen(yytext);
587       if (length<7 || length>=256)
588       {
589 #ifdef WZD_DBG_COOKIES
590         out_err(LEVEL_HIGH,"invalid for loop");
591 #endif
592         return 1;
593       }
594       memcpy(condition,yytext+5,length-6); /* 6 = strlen("%for()") */
595       condition[length-6]='\0';
596       i=0;
597       tmpbuf = malloc(16384);
598 /*      printf("starting for loop (%s)\n",condition);*/
599       while ((cookie=yylex()) && cookie!=COOKIE_ENDFOR)
600       {
601         /*	if (i>=LOOP_MAX_LINES) {
602                 printf("too much lines in for loop (max %d\n)",LOOP_MAX_LINES);
603                 return 1;
604                 }*/
605         if ( (i+strlen(yytext)) >= 16384 ) {
606 #ifdef WZD_DBG_COOKIES
607           out_err(LEVEL_HIGH,"loop TOO LONG !");
608 #endif
609           exit(1);
610         }
611         while (yytext[0] && (yytext[0] == '\r' || yytext[0] == '\n')) yytext++;
612         strcpy(tmpbuf+i,yytext);
613 /*        printf("%sMARK\n",yytext);*/
614         i+=strlen(yytext);
615       }
616       if (cookie) {
617 /*        printf("End of for loop (i=%d)\n",i);*/
618         BEGIN(INITIAL);
619       } else {
620 #ifdef WZD_DBG_COOKIES
621         out_err(LEVEL_HIGH,"unterminated for loop");
622 #endif
623         return 1;
624       }
625       /* flush buffer before executing 'for' loop */
626 /*      printf("flushing buffer on FOR\n");*/
627       /* flush buffer */
628       if (out_buffer) {
629         unsigned int l = send_buffer_ptr;
630         if (l >= out_buffer_len) {
631 #ifdef WZD_DBG_COOKIES
632           out_err(LEVEL_HIGH,"buffer truncated !");
633 #endif
634           l = out_buffer_len - 1;
635         }
636         memcpy(out_buffer_ptr,send_buffer,l);
637         out_buffer_ptr[l] = '\0';
638         out_buffer_ptr += l;
639       } else {
640         send_buffer[send_buffer_ptr]='\0';
641         if (real_context)
642           send_message_raw(send_buffer,real_context);
643         send_buffer_ptr=0;
644       }
645       /* execute for loop */
646       if (strcmp(condition,"allusersconnected")==0)
647       {
648         wzd_user_t * loop_user;
649         for (elmnt=list_head(context_list); elmnt!=NULL; elmnt=list_next(elmnt))
650         {
651           loop_context = list_data(elmnt);
652           if (loop_context->magic == CONTEXT_MAGIC)
653           {
654             loop_user = GetUserByID(loop_context->userid);
655             current_user = loop_user;
656             current_context = loop_context;
657             if (loop_user && loop_user->username[0] != '\0') {
658               /* check if user is hidden */
659               if (loop_user->flags && strchr(loop_user->flags,FLAG_HIDDEN)
660                   && (me)
661                   && !strchr(me->flags,FLAG_SITEOP)
662                   && strcmp(loop_user->username,me->username)!=0) /* do not hide to self ! */
663                 continue;
664               /* check if user is ultrahidden */
665               if (loop_user->flags && strchr(loop_user->flags,FLAG_ULTRAHIDDEN)
666                   && (me)
667                   && strcmp(loop_user->username,me->username)!=0) /* do not hide to self ! */
668                 continue;
669             }
670             if (out_buffer)
671               cookie_parse_buffer_r(tmpbuf,loop_user,current_group,current_context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
672             else
673               cookie_parse_buffer_r(tmpbuf,loop_user,current_group,current_context,out_buffer_ptr,0);
674           }
675         }
676         current_user = user;
677         current_context = NULL;
678       } /* allusersconnected */
679       else if (strcmp(condition,"allusers")==0)
680       {
681         wzd_user_t * loop_user;
682         uid_t * uid_list;
683         uid_list = (uid_t*)backend_get_user(-2);
684         if (uid_list) {
685           for (i=0; uid_list[i] != (uid_t)-1; i++)
686           {
687             loop_user = GetUserByID(uid_list[i]);
688             current_user = loop_user;
689             if (loop_user && loop_user->username[0] != '\0') {
690 
691               /* check if user is ultrahidden */
692              if (loop_user->flags && strchr(loop_user->flags,FLAG_ULTRAHIDDEN)
693                && (me)
694                && strcmp(loop_user->username,me->username)!=0) /* do not hide to self ! */
695                continue;
696               if (out_buffer)
697                 cookie_parse_buffer_r(tmpbuf,loop_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
698               else
699                 cookie_parse_buffer_r(tmpbuf,loop_user,current_group,context,out_buffer_ptr,0);
700             }
701           }
702           current_user = user;
703           wzd_free(uid_list);
704         }
705       } /* allusers */
706       else if (strcmp(condition,"allgroups")==0)
707       {
708         wzd_group_t * loop_group;
709         gid_t * gid_list;
710         gid_list = (gid_t*)backend_get_group(-2);
711         if (gid_list) {
712           for (i=0; gid_list[i] != (gid_t)-1; i++)
713           {
714             loop_group = GetGroupByID(gid_list[i]);
715             current_group = loop_group;
716             if (loop_group && loop_group->groupname[0] != '\0') {
717               if (out_buffer)
718                 cookie_parse_buffer_r(tmpbuf,current_user,loop_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
719               else
720                 cookie_parse_buffer_r(tmpbuf,current_user,loop_group,context,out_buffer_ptr,0);
721             }
722           }
723           current_group = group;
724           wzd_free(gid_list);
725         }
726       } /* allgroups */
727       else if (strcmp(condition,"allgroupmembers")==0)
728       {
729         wzd_user_t * loop_user;
730         gid_t gid;
731         if (current_group) {
732           uid_t * uid_list;
733 
734           uid_list = (uid_t*)backend_get_user(-2);
735           if (uid_list) {
736             gid = GetGroupIDByName(current_group->groupname);
737             for (i=0; uid_list[i] != (uid_t)-1; i++)
738             {
739               loop_user = GetUserByID(uid_list[i]);
740               current_user = loop_user;
741               if (loop_user && loop_user->username[0] != '\0' && is_user_in_group(loop_user,gid)==1) {
742 
743                 /* check if user is ultrahidden */
744                 if (loop_user->flags && strchr(loop_user->flags,FLAG_ULTRAHIDDEN)
745                     && (me)
746                     && strcmp(loop_user->username,me->username)!=0) /* do not hide to self ! */
747                   continue;
748                 if (out_buffer)
749                   cookie_parse_buffer_r(tmpbuf,loop_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
750                 else
751                   cookie_parse_buffer_r(tmpbuf,loop_user,current_group,context,out_buffer_ptr,0);
752               }
753             }
754             wzd_free(uid_list);
755           }
756           current_user = user;
757         }
758       } /* allgroupmembers */
759       else if (strcmp(condition,"allvfs")==0)
760       {
761         current_vfs = mainConfig->vfs;
762         while(current_vfs)
763         {
764           if (out_buffer)
765             cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
766           else
767             cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,0);
768           current_vfs = current_vfs->next_vfs;
769         }
770       } /* allvfs */
771       free(tmpbuf);
772     }
773     break;
774     case COOKIE_INCLUDE:
775     {
776       wzd_cache_t * fp;
777       char * tmpbuf;
778       char filename[256];
779       char c;
780       unsigned int i=0;
781 	  u64_t size;
782 
783       c = input();
784       if (c != '(')
785       {
786 #ifdef WZD_DBG_COOKIES
787         out_err(LEVEL_HIGH, "invalid 'include' directive\n");
788 #endif
789         break;
790       }
791 
792       while ( (c=input()) && c != ')' && c != '\r' && c != '\n' && i < sizeof(filename))
793         filename[i++] = c;
794       if (c != ')') /* error */
795         break;
796       filename[i] = '\0';
797 
798 #ifdef WZD_DBG_COOKIES
799       out_err(LEVEL_HIGH,"  including [%s]\n", filename);
800 #endif
801 
802       /** \todo resolve realpath() before opening filename ? */
803       fp = wzd_cache_open(filename, O_RDONLY, 0);
804       if (!fp)
805       {
806 #ifdef WZD_DBG_COOKIES
807         out_err(LEVEL_HIGH, "invalid 'include' directive (could not open file)\n");
808 #endif
809         break; /* invalid file name */
810       }
811 
812       size = wzd_cache_getsize(fp);
813       if (size > INT_MAX) {
814         out_log(LEVEL_HIGH,"%s:%d can't allocate %" PRIu64 " bytes for a file, aborting\n",__FILE__,__LINE__,size);
815         wzd_cache_close(fp);
816         break;
817       }
818       i = (unsigned int)size;
819       tmpbuf = wzd_malloc(i+1);
820       if (wzd_cache_read(fp, tmpbuf, i) != (int)i) {
821 #ifdef WZD_DBG_COOKIES
822         out_err(LEVEL_HIGH, "invalid 'include' directive (error reading file)\n");
823 #endif
824         wzd_free(tmpbuf);
825         wzd_cache_close(fp);
826         break;
827       }
828       wzd_cache_close(fp);
829       tmpbuf[i] = '\0';
830 
831 
832       /* flush buffer before executing 'include' */
833 #ifdef WZD_DBG_COOKIES
834       out_log(LEVEL_HIGH,"flushing buffer on INCLUDE\n");
835 #endif
836       /* flush buffer */
837       if (out_buffer) {
838         unsigned int l = send_buffer_ptr;
839         if (l >= out_buffer_len) {
840 #ifdef WZD_DBG_COOKIES
841           out_err(LEVEL_HIGH,"buffer truncated !");
842 #endif
843           l = out_buffer_len - 1;
844         }
845         memcpy(out_buffer_ptr,send_buffer,l);
846         out_buffer_ptr[l] = '\0';
847         out_buffer_ptr += l;
848         send_buffer_ptr=0; /** \todo XXX i added this line, wasn'r present - could be a bug in all
849         other flushes (FOR, etc ?! */
850       } else {
851         send_buffer[send_buffer_ptr]='\0';
852         if (real_context)
853           send_message_raw(send_buffer,real_context);
854         send_buffer_ptr=0;
855       }
856 
857       if (out_buffer) {
858         cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
859 
860         i = strlen(out_buffer_ptr);
861         if (send_buffer_ptr + i >= sizeof(send_buffer)) {
862           out_log(LEVEL_HIGH, "Buffer overflow\n");
863           return 1;
864         }
865         memcpy(send_buffer+send_buffer_ptr, out_buffer_ptr, i);
866         send_buffer_ptr += i;
867       }
868       else
869         cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,0);
870 
871       wzd_free(tmpbuf);
872 
873       BEGIN(INITIAL);
874     }
875     break;
876 /*** Bandwidth cookies ***/
877     case COOKIE_TOTAL_DL2:
878       convert=1;
879     case COOKIE_TOTAL_DL:
880       get_cookie_format(yytext,&padding);
881       {
882         float speed;
883         wzd_context_t * it;
884 
885         /* iterate through users and sum */
886         speed = 0.f;
887         for (elmnt=list_head(context_list); elmnt!=NULL; elmnt=list_next(elmnt))
888         {
889           it = list_data(elmnt);
890           if (it->magic == CONTEXT_MAGIC)
891           {
892             if (it->current_action.token==TOK_RETR)
893               speed += it->current_dl_limiter.current_speed;
894           }
895         }
896         if (convert) {
897           bytes_to_unit(&speed,&c);
898           snprintf(internalbuffer,IBUFSIZE,"%.2f %c/s",speed,c);
899         } else
900           snprintf(internalbuffer,IBUFSIZE,"%.2f",speed);
901       }
902       cookie_ptr = internalbuffer;
903       cookie_length = strlen(cookie_ptr);
904       convert=0;
905       break;
906     case COOKIE_TOTAL_UL2:
907       convert=1;
908     case COOKIE_TOTAL_UL:
909       get_cookie_format(yytext,&padding);
910       {
911         float speed;
912         wzd_context_t * it;
913 
914         /* iterate through users and sum */
915         speed = 0.f;
916         for (elmnt=list_head(context_list); elmnt!=NULL; elmnt=list_next(elmnt))
917         {
918           it = list_data(elmnt);
919           if (it->magic == CONTEXT_MAGIC)
920           {
921             if ((it->current_action.token==TOK_STOR) ||
922                 (it->current_action.token==TOK_APPE))
923               speed += it->current_ul_limiter.current_speed;
924           }
925         }
926         if (convert) {
927           bytes_to_unit(&speed,&c);
928           snprintf(internalbuffer,IBUFSIZE,"%.2f %c/s",speed,c);
929         } else
930           snprintf(internalbuffer,IBUFSIZE,"%.2f",speed);
931       }
932       cookie_ptr = internalbuffer;
933       cookie_length = strlen(cookie_ptr);
934       convert=0;
935       break;
936 /*** Connecte users cookies ***/
937     case COOKIE_CONNECTED_MAX:
938       snprintf(internalbuffer,IBUFSIZE,"%d",mainConfig->max_threads);
939       cookie_ptr = internalbuffer;
940       cookie_length = strlen(cookie_ptr);
941       break;
942     case COOKIE_CONNECTED_USERS:
943       get_cookie_format(yytext,&padding);
944       {
945         unsigned int count=0;
946 
947         for (elmnt=list_head(context_list); elmnt!=NULL; elmnt=list_next(elmnt))
948         {
949           loop_context = list_data(elmnt);
950           if (loop_context->magic == CONTEXT_MAGIC)
951             count++;
952         }
953         snprintf(internalbuffer,IBUFSIZE,"%d",count);
954       }
955       cookie_ptr = internalbuffer;
956       cookie_length = strlen(cookie_ptr);
957       convert=0;
958       break;
959 /*** FILE cookies ***/
960     case COOKIE_FILECRC:
961       get_cookie_format(yytext,&padding);
962       if (context) {
963         unsigned long crc=0;
964         if ((context->current_action.token == TOK_RETR ||
965         context->current_action.token == TOK_STOR ||
966         context->current_action.token == TOK_APPE) &&
967         (!calc_crc32(context->current_action.arg,&crc,0,(unsigned long)-1)))
968         {
969           snprintf(internalbuffer,IBUFSIZE,"%lX",crc);
970         }
971         else
972           snprintf(internalbuffer,IBUFSIZE,"0");
973       }
974       else
975         snprintf(internalbuffer,IBUFSIZE,"filecrc");
976       cookie_ptr = internalbuffer;
977       cookie_length = strlen(cookie_ptr);
978       break;
979     case COOKIE_FILEPATH:
980       get_cookie_format(yytext,&padding);
981       if (context) {
982         switch (context->current_action.token) {
983         case TOK_RETR:
984         case TOK_STOR:
985         case TOK_APPE:
986           snprintf(internalbuffer,IBUFSIZE,"%s",context->current_action.arg);
987           break;
988         case TOK_MKD:
989         case TOK_DELE:
990           snprintf(internalbuffer,IBUFSIZE,"%s",context->current_action.arg);
991           break;
992         default:
993           snprintf(internalbuffer,IBUFSIZE,"(null)");
994         }
995       }
996       else
997         snprintf(internalbuffer,IBUFSIZE,"filepath");
998       cookie_ptr = internalbuffer;
999       cookie_length = strlen(cookie_ptr);
1000       break;
1001 /*** GROUP cookies ***/
1002     case COOKIE_GROUPHOME:
1003       get_cookie_format(yytext,&padding);
1004       if (current_group)
1005         snprintf(internalbuffer,IBUFSIZE,"%s",current_group->defaultpath);
1006       else
1007         snprintf(internalbuffer,IBUFSIZE,"grouphome");
1008       cookie_ptr = internalbuffer;
1009       cookie_length = strlen(cookie_ptr);
1010       break;
1011     case COOKIE_GROUPID:
1012       get_cookie_format(yytext,&padding);
1013       if (current_group)
1014         snprintf(internalbuffer,IBUFSIZE,"%u",current_group->gid);
1015       else
1016         snprintf(internalbuffer,IBUFSIZE,"groupid");
1017       cookie_ptr = internalbuffer;
1018       cookie_length = strlen(cookie_ptr);
1019       break;
1020     case COOKIE_GROUPIP_ALLOW:
1021       get_cookie_format(yytext,&padding);
1022       {
1023         unsigned long index;
1024         char *ptr;
1025         char *numstart;
1026         /* we can suppress check here, flex has already done his work */
1027         numstart = yytext+strlen(yytext)-1;
1028         while ( isdigit(*(numstart-1)) ) numstart--;
1029         index = strtoul(numstart,&ptr,10);
1030         if (index<HARD_IP_PER_GROUP)
1031         {
1032           if (current_group) {
1033             unsigned int i=0;
1034             struct wzd_ip_list_t * it = current_group->ip_list;
1035             while (i < index) {
1036               if (it == NULL) break;
1037               it = it->next_ip;
1038               i++;
1039             }
1040             if (it != NULL)
1041               snprintf(internalbuffer,IBUFSIZE,"%s",it->regexp);
1042             else
1043               internalbuffer[0] = '\0';
1044           }
1045           else
1046             snprintf(internalbuffer,IBUFSIZE,"usergroup_allow");
1047         } else {
1048           snprintf(internalbuffer,IBUFSIZE,"invalid index");
1049         }
1050       }
1051       cookie_ptr = internalbuffer;
1052       cookie_length = strlen(cookie_ptr);
1053       break;
1054     case COOKIE_GROUPMAXDL:
1055       get_cookie_format(yytext,&padding);
1056       if (current_group)
1057       {
1058         snprintf(internalbuffer,IBUFSIZE,"%u",current_group->max_dl_speed);
1059       }
1060       else
1061         snprintf(internalbuffer,IBUFSIZE,"groupmaxdl");
1062       cookie_ptr = internalbuffer;
1063       cookie_length = strlen(cookie_ptr);
1064       break;
1065     case COOKIE_GROUPMAXIDLE:
1066       get_cookie_format(yytext,&padding);
1067       if (current_group)
1068       {
1069         snprintf(internalbuffer,IBUFSIZE,"%u",current_group->max_idle_time);
1070       }
1071       else
1072         snprintf(internalbuffer,IBUFSIZE,"groupmaxidle");
1073       cookie_ptr = internalbuffer;
1074       cookie_length = strlen(cookie_ptr);
1075       break;
1076     case COOKIE_GROUPMAXUL:
1077       get_cookie_format(yytext,&padding);
1078       if (current_group)
1079       {
1080         snprintf(internalbuffer,IBUFSIZE,"%u",current_group->max_ul_speed);
1081       }
1082       else
1083         snprintf(internalbuffer,IBUFSIZE,"groupmaxul");
1084       cookie_ptr = internalbuffer;
1085       cookie_length = strlen(cookie_ptr);
1086       break;
1087      case COOKIE_GROUPNAME:
1088       get_cookie_format(yytext,&padding);
1089       if (current_group)
1090         snprintf(internalbuffer,IBUFSIZE,"%s",current_group->groupname);
1091       else
1092         snprintf(internalbuffer,IBUFSIZE,"groupname");
1093       cookie_ptr = internalbuffer;
1094       cookie_length = strlen(cookie_ptr);
1095       break;
1096     case COOKIE_GROUPNUM_LOGINS:
1097       get_cookie_format(yytext,&padding);
1098       if (current_group)
1099       {
1100         snprintf(internalbuffer,IBUFSIZE,"%d",current_group->num_logins);
1101       }
1102       else
1103         snprintf(internalbuffer,IBUFSIZE,"groupnum_logins");
1104       cookie_ptr = internalbuffer;
1105       cookie_length = strlen(cookie_ptr);
1106       break;
1107     case COOKIE_GROUPRATIO:
1108       get_cookie_format(yytext,&padding);
1109       if (current_group)
1110       {
1111         if (current_group->ratio)
1112           snprintf(internalbuffer,IBUFSIZE,"1:%u",current_group->ratio);
1113         else
1114           snprintf(internalbuffer,IBUFSIZE,"unlimited");
1115       }
1116       else
1117         snprintf(internalbuffer,IBUFSIZE,"groupratio");
1118       cookie_ptr = internalbuffer;
1119       cookie_length = strlen(cookie_ptr);
1120       break;
1121     case COOKIE_GROUPTAG:
1122       get_cookie_format(yytext,&padding);
1123       if (current_group) {
1124         if (strlen(current_group->tagline)>0)
1125           snprintf(internalbuffer,IBUFSIZE,"%s",current_group->tagline);
1126         else
1127           snprintf(internalbuffer,IBUFSIZE,"no tagline set");
1128       }
1129       else
1130         snprintf(internalbuffer,IBUFSIZE,"grouptag");
1131       cookie_ptr = internalbuffer;
1132       cookie_length = strlen(cookie_ptr);
1133       break;
1134     case COOKIE_GROUPTOTAL_DL2:
1135       convert=1;
1136     case COOKIE_GROUPTOTAL_DL:
1137       get_cookie_format(yytext,&padding);
1138       if (current_group)
1139       {
1140         int gid;
1141         wzd_user_t * loop_user;
1142         int * uid_list;
1143         /* iterate through users and sum */
1144         gid = GetGroupIDByName(current_group->groupname);
1145         total = 0;
1146         uid_list = (int*)backend_get_user(-2);
1147         if (uid_list) {
1148           for (i=0; uid_list[i] >= 0; i++)
1149           {
1150             loop_user = GetUserByID(uid_list[i]);
1151             if (!loop_user) continue;
1152             if (is_user_in_group(loop_user,gid)==1)
1153             {
1154               total += loop_user->stats.bytes_dl_total;
1155             }
1156           }
1157           wzd_free(uid_list);
1158         }
1159         if (convert) {
1160 #ifndef _MSC_VER
1161           val = (float)total;
1162 #else
1163           val = (float)(__int64)total;
1164 #endif
1165           bytes_to_unit(&val,&c);
1166           snprintf(internalbuffer,IBUFSIZE,"%.2f %c",val,c);
1167         } else
1168           snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,total);
1169       }
1170       else
1171         snprintf(internalbuffer,IBUFSIZE,"grouptotal_dl");
1172       cookie_ptr = internalbuffer;
1173       cookie_length = strlen(cookie_ptr);
1174       convert=0;
1175       break;
1176     case COOKIE_GROUPTOTAL_UL2:
1177       convert=1;
1178     case COOKIE_GROUPTOTAL_UL:
1179       get_cookie_format(yytext,&padding);
1180       if (current_group)
1181       {
1182         int gid;
1183         wzd_user_t * loop_user;
1184         int * uid_list;
1185         /* iterate through users and sum */
1186         gid = GetGroupIDByName(current_group->groupname);
1187         total = 0;
1188         uid_list = (int*)backend_get_user(-2);
1189         if (uid_list) {
1190           for (i=0; uid_list[i] >= 0; i++)
1191           {
1192             loop_user = GetUserByID(uid_list[i]);
1193             if (!loop_user) continue;
1194             if (is_user_in_group(loop_user,gid)==1)
1195             {
1196               total += loop_user->stats.bytes_ul_total;
1197             }
1198           }
1199           wzd_free(uid_list);
1200         }
1201         if (convert) {
1202 #ifndef _MSC_VER
1203           val = (float)total;
1204 #else
1205           val = (float)(__int64)total;
1206 #endif
1207           bytes_to_unit(&val,&c);
1208           snprintf(internalbuffer,IBUFSIZE,"%.2f %c",val,c);
1209         } else
1210           snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,total);
1211       }
1212       else
1213         snprintf(internalbuffer,IBUFSIZE,"grouptotal_ul");
1214       cookie_ptr = internalbuffer;
1215       cookie_length = strlen(cookie_ptr);
1216       convert=0;
1217       break;
1218 /*** LAST FILE cookies ***/
1219     case COOKIE_LASTFILECRC:
1220       get_cookie_format(yytext,&padding);
1221       if (context)
1222         snprintf(internalbuffer,IBUFSIZE,"%08x",(context->last_file.name[0]!='\0')?context->last_file.crc:0);
1223       else
1224         snprintf(internalbuffer,IBUFSIZE,"crc");
1225       cookie_ptr = internalbuffer;
1226       cookie_length = strlen(cookie_ptr);
1227       break;
1228     case COOKIE_LASTFILENAME:
1229       get_cookie_format(yytext,&padding);
1230       if (context) {
1231         switch (context->last_file.token) {
1232         case TOK_RETR:
1233         case TOK_STOR:
1234         case TOK_APPE:
1235           snprintf(internalbuffer,IBUFSIZE,"%s",context->last_file.name);
1236           break;
1237         case TOK_MKD:
1238           snprintf(internalbuffer,IBUFSIZE,"%s",context->last_file.name);
1239           break;
1240         default:
1241           snprintf(internalbuffer,IBUFSIZE,"(null)");
1242         }
1243       }
1244       else
1245         snprintf(internalbuffer,IBUFSIZE,"lastfilename");
1246       cookie_ptr = internalbuffer;
1247       cookie_length = strlen(cookie_ptr);
1248       break;
1249     case COOKIE_LASTFILESIZE:
1250       get_cookie_format(yytext,&padding);
1251       if (context)
1252         /* use 64 bits here */
1253         snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,(context->last_file.name[0]!='\0')?context->last_file.size:0);
1254       else
1255         snprintf(internalbuffer,IBUFSIZE,"lastfilesize");
1256       cookie_ptr = internalbuffer;
1257       cookie_length = strlen(cookie_ptr);
1258       break;
1259     case COOKIE_LASTFILESPEED:
1260       get_cookie_format(yytext,&padding);
1261       if (context)
1262       {
1263 	    float f, time;
1264 #ifndef _MSC_VER
1265         f = (float)context->last_file.size;
1266 #else
1267         f = (float)(__int64)context->last_file.size;
1268 #endif
1269         if (context->last_file.name[0]!='\0')
1270         {
1271           time = (float)context->last_file.tv.tv_sec + ((float)context->last_file.tv.tv_usec/1000000.f);
1272           /** convert to kB/s ? */
1273           snprintf(internalbuffer,IBUFSIZE,"%.1f",
1274             ((time > 1e-5) ? (f / time) : 0.f) / 1024.f
1275             );
1276         }
1277         else
1278           snprintf(internalbuffer,IBUFSIZE,"0");
1279       }
1280       else
1281         snprintf(internalbuffer,IBUFSIZE,"lastfilespeed");
1282       cookie_ptr = internalbuffer;
1283       cookie_length = strlen(cookie_ptr);
1284       break;
1285     case COOKIE_LASTFILETIME:
1286       get_cookie_format(yytext,&padding);
1287       if (context)
1288         snprintf(internalbuffer,IBUFSIZE,"%.4f",(context->last_file.name[0]!='\0')?
1289         (float)context->last_file.tv.tv_sec + ((float)context->last_file.tv.tv_usec/1000000.f) :0);
1290       else
1291         snprintf(internalbuffer,IBUFSIZE,"lastfiletime");
1292       cookie_ptr = internalbuffer;
1293       cookie_length = strlen(cookie_ptr);
1294       break;
1295 /*** FILES cookies ***/
1296     case COOKIE_MSG:
1297     {
1298       wzd_cache_t * file;
1299       char * tmpbuf;
1300       char buffer[IBUFSIZE];
1301       int length;
1302       unsigned int size;
1303 	  u64_t sz64;
1304 
1305       if (!mainConfig->dir_message) {
1306         cookie_ptr = internalbuffer;
1307         cookie_length = 0;
1308         break;
1309       }
1310 
1311       if (checkpath_new(".",buffer,context)) {
1312         snprintf(internalbuffer,IBUFSIZE,"Could not get current path");
1313         cookie_ptr = internalbuffer;
1314         cookie_length = strlen(cookie_ptr);
1315         break;
1316       } else {
1317         length = strlen(buffer);
1318         if (buffer[length-1] != '/') buffer[length++] = '/';
1319         strncpy(buffer+length,mainConfig->dir_message,IBUFSIZE-length-1);
1320         file = wzd_cache_open(buffer,O_RDONLY,0666);
1321         if (!file) {
1322           cookie_ptr = NULL;
1323           cookie_length = 0;
1324           break;
1325         }
1326         sz64 = wzd_cache_getsize(file);
1327         if (sz64 > INT_MAX) {
1328           out_log(LEVEL_HIGH,"%s:%d can't allocate %" PRIu64 " bytes for a file, aborting\n",__FILE__,__LINE__,sz64);
1329               wzd_cache_close(file);
1330               cookie_ptr = NULL;
1331               cookie_length = 0;
1332               break;
1333         }
1334         size = (unsigned int)sz64;
1335         if (size >= out_buffer_len) { /* is it a good condition ? */
1336 #ifdef WZD_DBG_COOKIES
1337           out_err(LEVEL_HIGH,"buffer truncated !");
1338 #endif
1339           size = out_buffer_len - size;
1340         }
1341         tmpbuf = wzd_malloc(size+1);
1342         wzd_cache_read(file,tmpbuf,size);
1343         tmpbuf[size] = '\0';
1344         wzd_cache_close(file);
1345 
1346         if (out_buffer)
1347           cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,out_buffer_len+(out_buffer_ptr - out_buffer));
1348         else
1349           cookie_parse_buffer_r(tmpbuf,current_user,current_group,context,out_buffer_ptr,0);
1350 
1351         wzd_free(tmpbuf);
1352 
1353         cookie_ptr = out_buffer_ptr;
1354         cookie_length = strlen(cookie_ptr);
1355       }
1356     }
1357     break;
1358 /*** SECTION cookies ***/
1359     case COOKIE_SECTIONNAME:
1360     {
1361       wzd_section_t * section;
1362       section = section_find(mainConfig->section_list,context->currentpath);
1363       snprintf(internalbuffer,IBUFSIZE,"%s",(section)?section_getname(section):"none");
1364       cookie_ptr = internalbuffer;
1365       cookie_length = strlen(cookie_ptr);
1366     }
1367       break;
1368 /*** DISK/SPACE cookies ***/
1369     case COOKIE_SPACEFREE:
1370     {
1371       char dev_buffer[2048];
1372       long l_type, l_bsize, l_blocks, l_free;
1373       float f_blocks, f_free;
1374       char unit_blocks, unit_free;
1375       int ret;
1376 
1377       if (context == NULL || checkpath_new(".",dev_buffer,context) != 0) {
1378         snprintf(internalbuffer,IBUFSIZE,"Could not get current path");
1379       } else {
1380         ret = get_device_info(dev_buffer,&l_type, &l_bsize, &l_blocks, &l_free);
1381         f_blocks = l_blocks*(float)l_bsize;
1382         f_free = l_free*(float)l_bsize;
1383         bytes_to_unit(&f_blocks,&unit_blocks);
1384         bytes_to_unit(&f_free,&unit_free);
1385         snprintf(internalbuffer,IBUFSIZE,"%.2f %c",f_free,unit_free);
1386       }
1387       cookie_ptr = internalbuffer;
1388       cookie_length = strlen(cookie_ptr);
1389     }
1390       break;
1391     case COOKIE_SPACETOTAL:
1392     {
1393       char dev_buffer[2048];
1394       long l_type, l_bsize, l_blocks, l_free;
1395       float f_blocks, f_free;
1396       char unit_blocks, unit_free;
1397       int ret;
1398 
1399       if (checkpath_new(".",dev_buffer,context)) {
1400         snprintf(internalbuffer,IBUFSIZE,"Could not get current path");
1401       } else {
1402         ret = get_device_info(dev_buffer,&l_type, &l_bsize, &l_blocks, &l_free);
1403         f_blocks = l_blocks*(float)l_bsize;
1404         f_free = l_free*(float)l_bsize;
1405         bytes_to_unit(&f_blocks,&unit_blocks);
1406         bytes_to_unit(&f_free,&unit_free);
1407         snprintf(internalbuffer,IBUFSIZE,"%.2f %c",f_blocks,unit_blocks);
1408       }
1409       cookie_ptr = internalbuffer;
1410       cookie_length = strlen(cookie_ptr);
1411     }
1412       break;
1413 /*** USER cookies ***/
1414     case COOKIE_USERCREDITS2:
1415       convert = 1;
1416     case COOKIE_USERCREDITS:
1417       get_cookie_format(yytext,&padding);
1418       if (current_user)
1419       {
1420         if (current_user->ratio)
1421         {
1422           total = current_user->credits;
1423           if (convert) {
1424 #ifndef _MSC_VER
1425             val = (float)total;
1426 #else
1427             val = (float)(__int64)total;
1428 #endif
1429             bytes_to_unit(&val,&c);
1430             snprintf(internalbuffer,IBUFSIZE,"%.2f %c",val,c);
1431           } else
1432             snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,total);
1433         } else
1434           snprintf(internalbuffer,IBUFSIZE,"unlimited");
1435       }
1436       else
1437         snprintf(internalbuffer,IBUFSIZE,"usercredits");
1438       cookie_ptr = internalbuffer;
1439       cookie_length = strlen(cookie_ptr);
1440       convert=0;
1441       break;
1442     case COOKIE_USERFILES_DL:
1443       get_cookie_format(yytext,&padding);
1444       if (current_user)
1445         snprintf(internalbuffer,IBUFSIZE,"%lu",current_user->stats.files_dl_total);
1446       else
1447         snprintf(internalbuffer,IBUFSIZE,"userfiles_dl");
1448       cookie_ptr = internalbuffer;
1449       cookie_length = strlen(cookie_ptr);
1450       break;
1451     case COOKIE_USERFILES_UL:
1452       get_cookie_format(yytext,&padding);
1453       if (current_user)
1454         snprintf(internalbuffer,IBUFSIZE,"%lu",current_user->stats.files_ul_total);
1455       else
1456         snprintf(internalbuffer,IBUFSIZE,"userfiles_ul");
1457       cookie_ptr = internalbuffer;
1458       cookie_length = strlen(cookie_ptr);
1459       break;
1460     case COOKIE_USERFLAGS:
1461       get_cookie_format(yytext,&padding);
1462       if (current_user)
1463       {
1464         if (current_user->flags && strlen(current_user->flags)>0)
1465           snprintf(internalbuffer,IBUFSIZE,"%s",current_user->flags);
1466         else
1467           snprintf(internalbuffer,IBUFSIZE,"no flags");
1468       }
1469       else
1470         snprintf(internalbuffer,IBUFSIZE,"userflags");
1471       cookie_ptr = internalbuffer;
1472       cookie_length = strlen(cookie_ptr);
1473       break;
1474     case COOKIE_USERGROUP:
1475       get_cookie_format(yytext,&padding);
1476       {
1477         wzd_group_t * group;
1478         if (current_user && current_user->group_num>0)
1479         {
1480           group = GetGroupByID(current_user->groups[0]);
1481           if (group) {
1482             snprintf(internalbuffer,IBUFSIZE,"%s",group->groupname);
1483           }
1484           else {
1485             snprintf(internalbuffer,IBUFSIZE,"invalid group");
1486           }
1487         }
1488         else
1489         {
1490           snprintf(internalbuffer,IBUFSIZE,"nogroup");
1491         }
1492         cookie_ptr = internalbuffer;
1493         cookie_length = strlen(cookie_ptr);
1494       }
1495       break;
1496     case COOKIE_USERGROUPS:
1497       get_cookie_format(yytext,&padding);
1498       {
1499         wzd_group_t * group;
1500         length = IBUFSIZE;
1501         cookie_ptr = internalbuffer;
1502         i = 0;
1503         if (current_user && current_user->group_num > 0) {
1504           while (current_user && (unsigned int)i < current_user->group_num)
1505           {
1506             group = GetGroupByID(current_user->groups[i]);
1507             if (group) {
1508               snprintf(cookie_ptr,length,"%s ",group->groupname);
1509               length -= strlen(group->groupname) + 1;
1510               cookie_ptr += strlen(group->groupname) + 1;
1511             }
1512             i++;
1513           }
1514           internalbuffer[strlen(internalbuffer)-1] = '\0';
1515         }
1516         else
1517         {
1518           snprintf(internalbuffer,IBUFSIZE,"nogroup");
1519         }
1520         cookie_ptr = internalbuffer;
1521         cookie_length = strlen(cookie_ptr);
1522       }
1523       break;
1524     case COOKIE_USERHOME:
1525       get_cookie_format(yytext,&padding);
1526       if (current_user) {
1527         wzd_user_t * user = NULL;
1528         /* check FLAG_SEE_HOME for self */
1529         if (real_context) user = GetUserByID(real_context->userid);
1530         if ( (user && strcmp(current_user->username,user->username)==0 ) || /* self */
1531           (me && me->flags && strchr(me->flags,FLAG_SEE_HOME))) /* authorized */
1532           snprintf(internalbuffer,IBUFSIZE,"%s",current_user->rootpath);
1533         else /* not allowed to see */
1534           snprintf(internalbuffer,IBUFSIZE,"- some where -");
1535       }
1536       else
1537         snprintf(internalbuffer,IBUFSIZE,"userhome");
1538       cookie_ptr = internalbuffer;
1539       cookie_length = strlen(cookie_ptr);
1540       break;
1541     case COOKIE_USERID:
1542       get_cookie_format(yytext,&padding);
1543       if (current_user)
1544         snprintf(internalbuffer,IBUFSIZE,"%u",current_user->uid);
1545       else
1546         snprintf(internalbuffer,IBUFSIZE,"userid");
1547       cookie_ptr = internalbuffer;
1548       cookie_length = strlen(cookie_ptr);
1549       break;
1550     case COOKIE_USERIP:
1551       get_cookie_format(yytext,&padding);
1552       if (current_context)
1553       {
1554         int af = (context->family == WZD_INET6) ? AF_INET6 : AF_INET;
1555         /* check FLAG_SEE_IP for self */
1556         if (me && me->flags && strchr(me->flags,FLAG_SEE_IP)) {
1557           inet_ntop(af,current_context->hostip,internalbuffer,sizeof(internalbuffer));
1558         } else { /* not allowed to see */
1559           snprintf(internalbuffer,IBUFSIZE,"xxx.xxx.xxx.xxx");
1560         }
1561       }
1562       else
1563         snprintf(internalbuffer,IBUFSIZE,"userip");
1564       cookie_ptr = internalbuffer;
1565       cookie_length = strlen(cookie_ptr);
1566       break;
1567     case COOKIE_USERIP_ALLOW:
1568       get_cookie_format(yytext,&padding);
1569       {
1570         unsigned long index;
1571         char *ptr;
1572         char *numstart;
1573         /* we can suppress check here, flex has already done his work */
1574         numstart = yytext+strlen(yytext)-1;
1575         while ( isdigit(*(numstart-1)) ) numstart--;
1576         index = strtoul(numstart,&ptr,10);
1577         if (index<HARD_IP_PER_USER)
1578         {
1579           if (current_user) {
1580             unsigned int i=0;
1581             struct wzd_ip_list_t * it = current_user->ip_list;
1582             while (i < index) {
1583               if (it == NULL) break;
1584               it = it->next_ip;
1585               i++;
1586             }
1587             if (it != NULL)
1588               snprintf(internalbuffer,IBUFSIZE,"%s",it->regexp);
1589             else
1590               internalbuffer[0] = '\0';
1591           }
1592           else
1593             snprintf(internalbuffer,IBUFSIZE,"userip_allow");
1594         } else {
1595           snprintf(internalbuffer,IBUFSIZE,"invalid index");
1596         }
1597       }
1598       cookie_ptr = internalbuffer;
1599       cookie_length = strlen(cookie_ptr);
1600       break;
1601     case COOKIE_USERLASTCMD:
1602       get_cookie_format(yytext,&padding);
1603       if (current_context)
1604       {
1605         snprintf(internalbuffer,IBUFSIZE,"%s",str_tochar(current_context->current_action.command));
1606         if (strncasecmp(internalbuffer,"site",4)==0)
1607         {
1608           strcpy(internalbuffer,"SITE command");
1609         }
1610         if (strncasecmp(internalbuffer,"pass",4)==0)
1611         {
1612           strcpy(internalbuffer,"PASS xxxxx");
1613         }
1614       }
1615       else
1616         snprintf(internalbuffer,IBUFSIZE,"userlastcmd");
1617       cookie_ptr = internalbuffer;
1618       cookie_length = strlen(cookie_ptr);
1619       break;
1620     case COOKIE_USERLAST_LOGIN:
1621       get_cookie_format(yytext,&padding);
1622       if (current_user)
1623       {
1624         if (user->last_login) {
1625           struct tm *ntime;
1626           ntime=localtime(&user->last_login);
1627 		  if (ntime)
1628 			strftime(internalbuffer,IBUFSIZE,"%b %d %H:%M",ntime);
1629 		  else
1630 		    snprintf(internalbuffer,IBUFSIZE,"never");
1631         } else
1632           snprintf(internalbuffer,IBUFSIZE,"never");
1633       }
1634       else
1635         snprintf(internalbuffer,IBUFSIZE,"userlast_login");
1636       cookie_ptr = internalbuffer;
1637       cookie_length = strlen(cookie_ptr);
1638       break;
1639     case COOKIE_USERLEECHSLOTS:
1640       get_cookie_format(yytext,&padding);
1641       if (current_user)
1642       {
1643         snprintf(internalbuffer,IBUFSIZE,"%hu",current_user->leech_slots);
1644       }
1645       else
1646         snprintf(internalbuffer,IBUFSIZE,"userleechslots");
1647       cookie_ptr = internalbuffer;
1648       cookie_length = strlen(cookie_ptr);
1649       break;
1650     case COOKIE_USERMAXDL:
1651       get_cookie_format(yytext,&padding);
1652       if (current_user)
1653       {
1654         snprintf(internalbuffer,IBUFSIZE,"%u",current_user->max_dl_speed);
1655       }
1656       else
1657         snprintf(internalbuffer,IBUFSIZE,"usermaxdl");
1658       cookie_ptr = internalbuffer;
1659       cookie_length = strlen(cookie_ptr);
1660       break;
1661     case COOKIE_USERMAXIDLE:
1662       get_cookie_format(yytext,&padding);
1663       if (current_user)
1664       {
1665         snprintf(internalbuffer,IBUFSIZE,"%u",current_user->max_idle_time);
1666       }
1667       else
1668         snprintf(internalbuffer,IBUFSIZE,"usermaxidle");
1669       cookie_ptr = internalbuffer;
1670       cookie_length = strlen(cookie_ptr);
1671       break;
1672     case COOKIE_USERMAXUL:
1673       get_cookie_format(yytext,&padding);
1674       if (current_user)
1675       {
1676         snprintf(internalbuffer,IBUFSIZE,"%u",current_user->max_ul_speed);
1677       }
1678       else
1679         snprintf(internalbuffer,IBUFSIZE,"usermaxul");
1680       cookie_ptr = internalbuffer;
1681       cookie_length = strlen(cookie_ptr);
1682       break;
1683     case COOKIE_USERNAME:
1684       get_cookie_format(yytext,&padding);
1685       if (current_user)
1686         snprintf(internalbuffer,IBUFSIZE,"%s",current_user->username);
1687       else
1688         snprintf(internalbuffer,IBUFSIZE,"username");
1689       cookie_ptr = internalbuffer;
1690       cookie_length = strlen(cookie_ptr);
1691       break;
1692     case COOKIE_USERNUM_LOGINS:
1693       get_cookie_format(yytext,&padding);
1694       if (current_user)
1695       {
1696         snprintf(internalbuffer,IBUFSIZE,"%d",current_user->num_logins);
1697       }
1698       else
1699         snprintf(internalbuffer,IBUFSIZE,"usernum_logins");
1700       cookie_ptr = internalbuffer;
1701       cookie_length = strlen(cookie_ptr);
1702       break;
1703     case COOKIE_USERPATH:
1704       get_cookie_format(yytext,&padding);
1705       if (context) {
1706         char dev_buffer[WZD_MAX_PATH+1];
1707         wzd_user_t * user = NULL;
1708 
1709         if (real_context) user = GetUserByID(real_context->userid);
1710         /* check FLAG_SEE_HOME for self */
1711         if ( me &&
1712           ((user && strcmp(me->username,user->username)==0) ||
1713           (me->flags && strchr(me->flags,FLAG_SEE_HOME))) ) {
1714           if (checkpath_new(context->currentpath,dev_buffer,context)) {
1715             snprintf(internalbuffer,IBUFSIZE,"Could not get current path");
1716           } else {
1717             strncpy(internalbuffer,dev_buffer,IBUFSIZE);
1718           }
1719         } else {
1720           snprintf(internalbuffer,IBUFSIZE,"- some where -");
1721         }
1722       }
1723       else
1724         snprintf(internalbuffer,IBUFSIZE,"userpwd");
1725       cookie_ptr = internalbuffer;
1726       cookie_length = strlen(cookie_ptr);
1727       break;
1728     case COOKIE_USERPID:
1729       get_cookie_format(yytext,&padding);
1730       if (current_context)
1731       {
1732         /* check FLAG_SITEOP for self */
1733         if (me && me->flags && strchr(me->flags,FLAG_SITEOP))
1734           snprintf(internalbuffer,IBUFSIZE,"%lu",current_context->pid_child);
1735         else
1736           snprintf(internalbuffer,IBUFSIZE,"some id");
1737       }
1738       else
1739         snprintf(internalbuffer,IBUFSIZE,"userpid");
1740       cookie_ptr = internalbuffer;
1741       cookie_length = strlen(cookie_ptr);
1742       break;
1743     case COOKIE_USERPWD:
1744       get_cookie_format(yytext,&padding);
1745       if (context) {
1746         snprintf(internalbuffer,IBUFSIZE,"%s",context->currentpath);
1747       }
1748       else
1749         snprintf(internalbuffer,IBUFSIZE,"userpwd");
1750       cookie_ptr = internalbuffer;
1751       cookie_length = strlen(cookie_ptr);
1752       break;
1753     case COOKIE_USERRATIO:
1754       get_cookie_format(yytext,&padding);
1755       if (current_user)
1756       {
1757         if (current_user->ratio)
1758           snprintf(internalbuffer,IBUFSIZE,"1:%u",current_user->ratio);
1759         else
1760           snprintf(internalbuffer,IBUFSIZE,"unlimited");
1761       }
1762       else
1763         snprintf(internalbuffer,IBUFSIZE,"userratio");
1764       cookie_ptr = internalbuffer;
1765       cookie_length = strlen(cookie_ptr);
1766       break;
1767     case COOKIE_USERSLOTS:
1768       get_cookie_format(yytext,&padding);
1769       if (current_user)
1770       {
1771         snprintf(internalbuffer,IBUFSIZE,"%hu",current_user->user_slots);
1772       }
1773       else
1774         snprintf(internalbuffer,IBUFSIZE,"userslots");
1775       cookie_ptr = internalbuffer;
1776       cookie_length = strlen(cookie_ptr);
1777       break;
1778    case COOKIE_USERSPEED:
1779       get_cookie_format(yytext,&padding);
1780       if (current_context)
1781       {
1782         if (current_context->current_action.token==TOK_RETR)
1783           snprintf(internalbuffer,IBUFSIZE,"%.1f kB/s",current_context->current_dl_limiter.current_speed/1024.f);
1784         else {
1785           if ((current_context->current_action.token==TOK_STOR) ||
1786               (current_context->current_action.token==TOK_APPE))
1787           {
1788             snprintf(internalbuffer,IBUFSIZE,"%.1f kB/s",current_context->current_ul_limiter.current_speed/1024.f);
1789           }
1790           else
1791             internalbuffer[0]='\0';
1792         }
1793       }
1794       else
1795         snprintf(internalbuffer,IBUFSIZE,"userspeed");
1796       cookie_ptr = internalbuffer;
1797       cookie_length = strlen(cookie_ptr);
1798       break;
1799    case COOKIE_USERTAG:
1800       get_cookie_format(yytext,&padding);
1801       if (current_user) {
1802         if (current_user->flags && strchr(current_user->flags,FLAG_DELETED)) {
1803           snprintf(internalbuffer,IBUFSIZE,"**DELETED**");
1804         } else {
1805           if (strlen(current_user->tagline)>0)
1806             snprintf(internalbuffer,IBUFSIZE,"%s",current_user->tagline);
1807           else
1808             snprintf(internalbuffer,IBUFSIZE,"no tagline set");
1809         }
1810       }
1811       else
1812         snprintf(internalbuffer,IBUFSIZE,"usertag");
1813       cookie_ptr = internalbuffer;
1814       cookie_length = strlen(cookie_ptr);
1815       break;
1816     case COOKIE_USERTIME:
1817       get_cookie_format(yytext,&padding);
1818       if (current_user)
1819       {
1820         snprintf(internalbuffer,IBUFSIZE,"%s",time_to_str(time(NULL) - current_context->login_time));
1821       }
1822       else
1823         snprintf(internalbuffer,IBUFSIZE,"usertime");
1824       cookie_ptr = internalbuffer;
1825       cookie_length = strlen(cookie_ptr);
1826       break;
1827    case COOKIE_USERTOTAL_DL2:
1828       convert = 1;
1829    case COOKIE_USERTOTAL_DL:
1830       get_cookie_format(yytext,&padding);
1831       if (current_user)
1832       {
1833         total = current_user->stats.bytes_dl_total;
1834         if (convert) {
1835 #ifndef _MSC_VER
1836           val = (float)total;
1837 #else
1838           val = (float)(__int64)total;
1839 #endif
1840           bytes_to_unit(&val,&c);
1841           snprintf(internalbuffer,IBUFSIZE,"%.2f %c",val,c);
1842         } else
1843           snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,total);
1844       }
1845       else
1846         snprintf(internalbuffer,IBUFSIZE,"usertotal_dl");
1847       cookie_ptr = internalbuffer;
1848       cookie_length = strlen(cookie_ptr);
1849       convert=0;
1850       break;
1851    case COOKIE_USERTOTAL_UL2:
1852       convert = 1;
1853    case COOKIE_USERTOTAL_UL:
1854       get_cookie_format(yytext,&padding);
1855       if (current_user)
1856       {
1857         total = current_user->stats.bytes_ul_total;
1858         if (convert) {
1859 #ifndef _MSC_VER
1860           val = (float)total;
1861 #else
1862           val = (float)(__int64)total;
1863 #endif
1864           bytes_to_unit(&val,&c);
1865           snprintf(internalbuffer,IBUFSIZE,"%.2f %c",val,c);
1866         } else
1867           snprintf(internalbuffer,IBUFSIZE,"%" PRIu64,total);
1868       }
1869       else
1870         snprintf(internalbuffer,IBUFSIZE,"usertotal_ul");
1871       cookie_ptr = internalbuffer;
1872       cookie_length = strlen(cookie_ptr);
1873       convert=0;
1874       break;
1875      /* XXX This is a little dansgerous because we don't know if strings
1876      * will be ok when used (although as address of constant data it should
1877      * always be ok) but we like sport !
1878      */
1879    case COOKIE_NOCOL:
1880       if (use_colors) {
1881         cookie_ptr = "";
1882         cookie_length = strlen(cookie_ptr);
1883       } else
1884         continue;
1885       break;
1886    case COOKIE_BLACK:
1887       if (use_colors) {
1888         cookie_ptr = "";
1889         cookie_length = strlen(cookie_ptr);
1890       } else
1891         continue;
1892       break;
1893    case COOKIE_RED:
1894       if (use_colors) {
1895         cookie_ptr = "";
1896         cookie_length = strlen(cookie_ptr);
1897       } else
1898         continue;
1899       break;
1900    case COOKIE_GREEN:
1901       if (use_colors) {
1902         cookie_ptr = "";
1903         cookie_length = strlen(cookie_ptr);
1904       } else
1905         continue;
1906       break;
1907    case COOKIE_BROWN:
1908       if (use_colors) {
1909         cookie_ptr = "";
1910         cookie_length = strlen(cookie_ptr);
1911       } else
1912         continue;
1913       break;
1914    case COOKIE_BLUE:
1915       if (use_colors) {
1916         cookie_ptr = "";
1917         cookie_length = strlen(cookie_ptr);
1918       } else
1919         continue;
1920       break;
1921    case COOKIE_MAGENTA:
1922       if (use_colors) {
1923         cookie_ptr = "";
1924         cookie_length = strlen(cookie_ptr);
1925       } else
1926         continue;
1927       break;
1928    case COOKIE_CYAN:
1929       if (use_colors) {
1930         cookie_ptr = "";
1931         cookie_length = strlen(cookie_ptr);
1932       } else
1933         continue;
1934       break;
1935    case COOKIE_WHITE:
1936       if (use_colors) {
1937         cookie_ptr = "";
1938         cookie_length = strlen(cookie_ptr);
1939       } else
1940         continue;
1941       break;
1942    case COOKIE_ENDFOR:
1943 #ifdef WZD_DBG_COOKIES
1944       out_err(LEVEL_HIGH,"endfor outside a for loop");
1945 #endif
1946       continue;
1947     case COOKIE_INVALID: /* e.g This can be an explicit %s */
1948       snprintf(internalbuffer,IBUFSIZE,"%%%s",yytext);
1949       cookie_ptr = internalbuffer;
1950       cookie_length = strlen(cookie_ptr);
1951       break;
1952     case COOKIE_EOL:
1953       cookie_ptr = "\r\n";
1954       cookie_length = 2;
1955       strncpy(send_buffer+send_buffer_ptr,cookie_ptr,cookie_length);
1956       send_buffer_ptr += cookie_length;
1957       if (send_buffer_ptr >= MIN_SEND_BUFFERSIZE) {
1958 #ifdef WZD_DBG_COOKIES
1959         out_err(LEVEL_HIGH,"flushing buffer on EOL");
1960 #endif
1961         /* flush buffer */
1962         if (out_buffer) {
1963           unsigned int l = send_buffer_ptr;
1964           if (l >= out_buffer_len) {
1965 #ifdef WZD_DBG_COOKIES
1966             out_err(LEVEL_HIGH,"buffer truncated !");
1967 #endif
1968             l = out_buffer_len - 1;
1969           }
1970           memcpy(out_buffer_ptr,send_buffer,l);
1971           out_buffer_ptr[l] = '\0';
1972           out_buffer_ptr += l;
1973           out_buffer_len -= l;
1974         } else {
1975           send_buffer[send_buffer_ptr]='\0';
1976           if (real_context)
1977             send_message_raw(send_buffer,real_context);
1978         }
1979         send_buffer_ptr=0;
1980       }
1981       continue;
1982     case COOKIE_VFSVIRTUAL:
1983       get_cookie_format(yytext,&padding);
1984       if (current_vfs)
1985         snprintf(internalbuffer,IBUFSIZE,"%s",current_vfs->virtual_dir);
1986       else
1987         snprintf(internalbuffer,IBUFSIZE,"virtual_dir");
1988       cookie_ptr = internalbuffer;
1989       cookie_length = strlen(cookie_ptr);
1990       break;
1991     case COOKIE_VFSPHYSICAL:
1992       get_cookie_format(yytext,&padding);
1993       if (current_vfs)
1994         snprintf(internalbuffer,IBUFSIZE,"%s",current_vfs->physical_dir);
1995       else
1996         snprintf(internalbuffer,IBUFSIZE,"physical_dir");
1997       cookie_ptr = internalbuffer;
1998       cookie_length = strlen(cookie_ptr);
1999       break;
2000     case COOKIE_VFSTARGET:
2001       get_cookie_format(yytext,&padding);
2002       if (current_vfs)
2003       {
2004         if (current_vfs->target)
2005           snprintf(internalbuffer,IBUFSIZE,"%s",current_vfs->target);
2006         else
2007           snprintf(internalbuffer,IBUFSIZE,"not restricted");
2008       }
2009 
2010       else
2011         snprintf(internalbuffer,IBUFSIZE,"target");
2012       cookie_ptr = internalbuffer;
2013       cookie_length = strlen(cookie_ptr);
2014       break;
2015     default:
2016       cookie_ptr = yytext;
2017       cookie_length = strlen(cookie_ptr);
2018       break;
2019     }
2020     if (cookie_ptr) {
2021       if (padding) {
2022         if (cookie_length < padding) {
2023           for (;cookie_length<padding;cookie_length++) {
2024             cookie_ptr[cookie_length] = ' '; /* FIXME padding char hardcoded */
2025           }
2026         }
2027         cookie_ptr[padding] = '\0';
2028         cookie_length = padding;
2029       }
2030       /*      printf("%s",cookie_ptr);
2031               fflush(stdout);*/
2032       /* bufferize and send only complete lines */
2033       if (send_buffer_ptr + cookie_length >= MAX_SEND_BUFFERSIZE) {
2034 #ifdef WZD_DBG_COOKIES
2035         out_err(LEVEL_HIGH,"flushing buffer on BUFFER OVERFLOW");
2036 #endif
2037         /* flush buffer */
2038         if (out_buffer) {
2039           unsigned int l = send_buffer_ptr;
2040           if (l >= out_buffer_len) {
2041 #ifdef WZD_DBG_COOKIES
2042             out_err(LEVEL_HIGH,"buffer truncated !");
2043 #endif
2044             l = out_buffer_len - 1;
2045           }
2046           memcpy(out_buffer_ptr,send_buffer,l);
2047           out_buffer_ptr[l] = '\0';
2048           out_buffer_ptr += l;
2049           out_buffer_len -= l;
2050         } else {
2051           send_buffer[send_buffer_ptr]='\0';
2052           if (real_context)
2053             send_message_raw(send_buffer,real_context);
2054         }
2055         send_buffer_ptr=0;
2056       }
2057       strncpy(send_buffer+send_buffer_ptr,cookie_ptr,cookie_length);
2058       send_buffer_ptr += cookie_length;
2059     }
2060   }
2061   if ( --cookie_include_stack_ptr < 0 )
2062     yyterminate();
2063   else
2064   {
2065     yy_delete_buffer( YY_CURRENT_BUFFER );
2066     yy_switch_to_buffer(include_stack[cookie_include_stack_ptr] );
2067   }
2068 
2069 #ifdef WZD_DBG_COOKIES
2070   out_err(LEVEL_HIGH,"flushing buffer on EOF (%d)",send_buffer_ptr);
2071 #endif
2072   /* flush buffer */
2073   if (send_buffer_ptr) {
2074     if (send_buffer_ptr>2) {
2075       if (send_buffer[send_buffer_ptr-2]!= '\r' || send_buffer[send_buffer_ptr-1]!='\n') {
2076         strncpy(send_buffer+send_buffer_ptr,"\r\n",strlen("\r\n"));
2077         send_buffer_ptr += strlen("\r\n");
2078       }
2079     }
2080     else {
2081       strncpy(send_buffer+send_buffer_ptr,"\r\n",strlen("\r\n"));
2082       send_buffer_ptr += strlen("\r\n");
2083     }
2084     send_buffer[send_buffer_ptr]='\0';
2085     if (out_buffer) {
2086       unsigned int l = send_buffer_ptr;
2087       if (l >= out_buffer_len) {
2088 #ifdef WZD_DBG_COOKIES
2089         out_err(LEVEL_HIGH,"buffer truncated !");
2090 #endif
2091         l = out_buffer_len - 1;
2092       }
2093       memcpy(out_buffer_ptr,send_buffer,l);
2094       out_buffer_ptr[l] = '\0';
2095       out_buffer_ptr += l;
2096       out_buffer_len -= l;
2097 #ifdef WZD_DBG_COOKIES
2098         out_err(LEVEL_HIGH,"buffer length %d (%d)",strlen(out_buffer),out_buffer_len);
2099 #endif
2100     } else {
2101       if (real_context)
2102         send_message_raw(send_buffer,real_context);
2103     }
2104     send_buffer_ptr=0;
2105   }
2106 
2107   return 0;
2108 }
2109 
2110