/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/storage_file.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/bnetd/storage_file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.1 /*
2     * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
3     * Copyright (C) 2000,2001 Marco Ziech (mmz@gmx.net)
4     * Copyright (C) 2002,2003,2004 Mihai RUSU (dizzy@rdsnet.ro)
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20     #include "common/setup_before.h"
21     #include <stdio.h>
22     #ifdef HAVE_STDDEF_H
23     # include <stddef.h>
24     #else
25     # ifndef NULL
26     # define NULL ((void *)0)
27     # endif
28     #endif
29     #ifdef STDC_HEADERS
30     # include <stdlib.h>
31     #else
32     # ifdef HAVE_MALLOC_H
33     # include <malloc.h>
34     # endif
35     #endif
36     #ifdef HAVE_STRING_H
37     # include <string.h>
38     #else
39     # ifdef HAVE_STRINGS_H
40     # include <strings.h>
41     # endif
42     #endif
43     #include "compat/strchr.h"
44     #include "compat/strdup.h"
45     #include "compat/strcasecmp.h"
46     #include "compat/strncasecmp.h"
47     #include <ctype.h>
48     #ifdef HAVE_LIMITS_H
49     # include <limits.h>
50     #endif
51     #include "compat/char_bit.h"
52     #ifdef TIME_WITH_SYS_TIME
53     # include <sys/time.h>
54     # include <time.h>
55     #else
56     # ifdef HAVE_SYS_TIME_H
57     # include <sys/time.h>
58     # else
59     # include <time.h>
60     # endif
61     #endif
62     #include <errno.h>
63     #include "compat/strerror.h"
64     #ifdef HAVE_SYS_TYPES_H
65     # include <sys/types.h>
66     #endif
67     #ifdef HAVE_UNISTD_H
68     # include <unistd.h>
69     #endif
70     #include "compat/access.h"
71     #include "compat/rename.h"
72     #include "compat/pdir.h"
73     #include "common/eventlog.h"
74     #include "prefs.h"
75     #include "common/util.h"
76     #include "common/field_sizes.h"
77     #include "common/bnethash.h"
78     #define CLAN_INTERNAL_ACCESS
79     #define TEAM_INTERNAL_ACCESS
80     #define ACCOUNT_INTERNAL_ACCESS
81     #include "common/introtate.h"
82     #include "team.h"
83     #include "account.h"
84     #include "common/hashtable.h"
85     #include "storage.h"
86     #include "storage_file.h"
87     #include "file_plain.h"
88     #include "file_cdb.h"
89     #include "common/list.h"
90     #include "connection.h"
91     #include "watch.h"
92     #include "clan.h"
93     #undef ACCOUNT_INTERNAL_ACCESS
94     #undef TEAM_INTERNAL_ACCESS
95     #undef CLAN_INTERNAL_ACCESS
96     #include "common/tag.h"
97     #include "common/xalloc.h"
98     #include "common/setup_after.h"
99    
100     /* file storage API functions */
101    
102     static int file_init(const char *);
103     static int file_close(void);
104     static unsigned file_read_maxuserid(void);
105     static t_storage_info *file_create_account(char const *);
106     static t_storage_info *file_get_defacct(void);
107     static int file_free_info(t_storage_info *);
108     static int file_read_attrs(t_storage_info *, t_read_attr_func, void *);
109     static void *file_read_attr(t_storage_info *, const char *);
110     static int file_write_attrs(t_storage_info *, void *);
111     static int file_read_accounts(int,t_read_accounts_func, void *);
112     static t_storage_info *file_read_account(const char *, unsigned);
113     static int file_cmp_info(t_storage_info *, t_storage_info *);
114     static const char *file_escape_key(const char *);
115     static int file_load_clans(t_load_clans_func);
116     static int file_write_clan(void *);
117     static int file_remove_clan(int);
118     static int file_remove_clanmember(int);
119     static int file_load_teams(t_load_teams_func);
120     static int file_write_team(void *);
121     static int file_remove_team(unsigned int);
122    
123     /* storage struct populated with the functions above */
124    
125     t_storage storage_file = {
126     file_init,
127     file_close,
128     file_read_maxuserid,
129     file_create_account,
130     file_get_defacct,
131     file_free_info,
132     file_read_attrs,
133     file_write_attrs,
134     file_read_attr,
135     file_read_accounts,
136     file_read_account,
137     file_cmp_info,
138     file_escape_key,
139     file_load_clans,
140     file_write_clan,
141     file_remove_clan,
142     file_remove_clanmember,
143     file_load_teams,
144     file_write_team,
145     file_remove_team
146     };
147    
148     /* start of actual file storage code */
149    
150     static const char *accountsdir = NULL;
151     static const char *clansdir = NULL;
152     static const char *teamsdir = NULL;
153     static const char *defacct = NULL;
154     static t_file_engine *file = NULL;
155    
156     static unsigned file_read_maxuserid(void)
157     {
158     return maxuserid;
159     }
160    
161     static int file_init(const char *path)
162     {
163     char *tok, *copy, *tmp, *p;
164     const char *dir = NULL;
165     const char *clan = NULL;
166     const char *team = NULL;
167     const char *def = NULL;
168     const char *driver = NULL;
169    
170     if (path == NULL || path[0] == '\0')
171     {
172     eventlog(eventlog_level_error, __FUNCTION__, "got NULL or empty path");
173     return -1;
174     }
175    
176     copy = xstrdup(path);
177     tmp = copy;
178     while ((tok = strtok(tmp, ";")) != NULL)
179     {
180     tmp = NULL;
181     if ((p = strchr(tok, '=')) == NULL)
182     {
183     eventlog(eventlog_level_error, __FUNCTION__, "invalid storage_path, no '=' present in token");
184     xfree((void *) copy);
185     return -1;
186     }
187     *p = '\0';
188     if (strcasecmp(tok, "dir") == 0)
189     dir = p + 1;
190     else if (strcasecmp(tok, "clan") == 0)
191     clan = p + 1;
192     else if (strcasecmp(tok, "team") == 0)
193     team = p + 1;
194     else if (strcasecmp(tok, "default") == 0)
195     def = p + 1;
196     else if (strcasecmp(tok, "mode") == 0)
197     driver = p + 1;
198     else
199     eventlog(eventlog_level_warn, __FUNCTION__, "unknown token in storage_path : '%s'", tok);
200     }
201    
202     if (def == NULL || clan == NULL || team == NULL || dir == NULL || driver == NULL)
203     {
204     eventlog(eventlog_level_error, __FUNCTION__, "invalid storage_path line for file module (doesnt have a 'dir', a 'clan', a 'team', a 'default' token and a 'mode' token)");
205     xfree((void *) copy);
206     return -1;
207     }
208    
209     if (!strcasecmp(driver, "plain"))
210     file = &file_plain;
211     else if (!strcasecmp(driver, "cdb"))
212     file = &file_cdb;
213     else
214     {
215     eventlog(eventlog_level_error, __FUNCTION__, "unknown mode '%s' must be either plain or cdb", driver);
216     xfree((void *) copy);
217     return -1;
218     }
219    
220     if (accountsdir)
221     file_close();
222    
223     accountsdir = xstrdup(dir);
224     clansdir = xstrdup(clan);
225     teamsdir = xstrdup(team);
226     defacct = xstrdup(def);
227    
228     xfree((void *) copy);
229    
230     return 0;
231     }
232    
233     static int file_close(void)
234     {
235     if (accountsdir)
236     xfree((void *) accountsdir);
237     accountsdir = NULL;
238    
239     if (clansdir)
240     xfree((void *) clansdir);
241     clansdir = NULL;
242    
243     if (teamsdir)
244     xfree((void *) teamsdir);
245     teamsdir = NULL;
246    
247     if (defacct)
248     xfree((void *) defacct);
249     defacct = NULL;
250    
251     file = NULL;
252    
253     return 0;
254     }
255    
256     static t_storage_info *file_create_account(const char *username)
257     {
258     char *temp;
259    
260     if (accountsdir == NULL || file == NULL)
261     {
262     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
263     return NULL;
264     }
265    
266     if (prefs_get_savebyname())
267     {
268     char const *safename;
269    
270     if (!strcmp(username, defacct))
271     {
272     eventlog(eventlog_level_error, __FUNCTION__, "username as defacct not allowed");
273     return NULL;
274     }
275    
276     if (!(safename = escape_fs_chars(username, strlen(username))))
277     {
278     eventlog(eventlog_level_error, __FUNCTION__, "could not escape username");
279     return NULL;
280     }
281     temp = xmalloc(strlen(accountsdir) + 1 + strlen(safename) + 1); /* dir + / + name + NUL */
282     sprintf(temp, "%s/%s", accountsdir, safename);
283     xfree((void *) safename); /* avoid warning */
284     } else
285     {
286     temp = xmalloc(strlen(accountsdir) + 1 + 8 + 1); /* dir + / + uid + NUL */
287     sprintf(temp, "%s/%06u", accountsdir, maxuserid + 1); /* FIXME: hmm, maybe up the %06 to %08... */
288     }
289    
290     return temp;
291     }
292    
293     static int file_write_attrs(t_storage_info * info, void *attributes)
294     {
295     char *tempname;
296    
297     if (accountsdir == NULL || file == NULL)
298     {
299     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
300     return -1;
301     }
302    
303     if (info == NULL)
304     {
305     eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage");
306     return -1;
307     }
308    
309     if (attributes == NULL)
310     {
311     eventlog(eventlog_level_error, __FUNCTION__, "got NULL attributes");
312     return -1;
313     }
314    
315     tempname = xmalloc(strlen(accountsdir) + 1 + strlen(BNETD_ACCOUNT_TMP) + 1);
316     sprintf(tempname, "%s/%s", accountsdir, BNETD_ACCOUNT_TMP);
317    
318     if (file->write_attrs(tempname, attributes))
319     {
320     /* no eventlog here, it should be reported from the file layer */
321     xfree(tempname);
322     return -1;
323     }
324    
325     if (p_rename(tempname, (const char *) info) < 0)
326     {
327     eventlog(eventlog_level_error, __FUNCTION__, "could not rename account file to \"%s\" (rename: %s)", (char *) info, pstrerror(errno));
328     xfree(tempname);
329     return -1;
330     }
331    
332     xfree(tempname);
333    
334     return 0;
335     }
336    
337     static int file_read_attrs(t_storage_info * info, t_read_attr_func cb, void *data)
338     {
339     if (accountsdir == NULL || file == NULL)
340     {
341     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
342     return -1;
343     }
344    
345     if (info == NULL)
346     {
347     eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage");
348     return -1;
349     }
350    
351     if (cb == NULL)
352     {
353     eventlog(eventlog_level_error, __FUNCTION__, "got NULL callback");
354     return -1;
355     }
356    
357     eventlog(eventlog_level_debug, __FUNCTION__, "loading \"%s\"", (char *) info);
358    
359     if (file->read_attrs((const char *) info, cb, data))
360     {
361     /* no eventlog, error reported earlier */
362     return -1;
363     }
364    
365     return 0;
366     }
367    
368     static void *file_read_attr(t_storage_info * info, const char *key)
369     {
370     if (accountsdir == NULL || file == NULL)
371     {
372     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
373     return NULL;
374     }
375    
376     if (info == NULL)
377     {
378     eventlog(eventlog_level_error, __FUNCTION__, "got NULL info storage");
379     return NULL;
380     }
381    
382     if (key == NULL)
383     {
384     eventlog(eventlog_level_error, __FUNCTION__, "got NULL key");
385     return NULL;
386     }
387    
388     return file->read_attr((const char *) info, key);
389     }
390    
391     static int file_free_info(t_storage_info * info)
392     {
393     if (info)
394     xfree((void *) info);
395     return 0;
396     }
397    
398     static t_storage_info *file_get_defacct(void)
399     {
400     t_storage_info *info;
401    
402     if (defacct == NULL)
403     {
404     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
405     return NULL;
406     }
407    
408     info = xstrdup(defacct);
409    
410     return info;
411     }
412    
413     static int file_read_accounts(int flag,t_read_accounts_func cb, void *data)
414     {
415     char const *dentry;
416     char *pathname;
417     t_pdir *accountdir;
418    
419     if (accountsdir == NULL)
420     {
421     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
422     return -1;
423     }
424    
425     if (cb == NULL)
426     {
427     eventlog(eventlog_level_error, __FUNCTION__, "got NULL callback");
428     return -1;
429     }
430    
431     if (!(accountdir = p_opendir(accountsdir)))
432     {
433     eventlog(eventlog_level_error, __FUNCTION__, "unable to open user directory \"%s\" for reading (p_opendir: %s)", accountsdir, pstrerror(errno));
434     return -1;
435     }
436    
437     while ((dentry = p_readdir(accountdir)))
438     {
439     if (dentry[0] == '.')
440     continue;
441    
442     pathname = xmalloc(strlen(accountsdir) + 1 + strlen(dentry) + 1); /* dir + / + file + NUL */
443     sprintf(pathname, "%s/%s", accountsdir, dentry);
444    
445     cb(pathname, data);
446     }
447    
448     if (p_closedir(accountdir) < 0)
449     eventlog(eventlog_level_error, __FUNCTION__, "unable to close user directory \"%s\" (p_closedir: %s)", accountsdir, pstrerror(errno));
450    
451     return 0;
452     }
453    
454     static t_storage_info *file_read_account(const char *accname, unsigned uid)
455     {
456     char *pathname;
457    
458     if (accountsdir == NULL)
459     {
460     eventlog(eventlog_level_error, __FUNCTION__, "file storage not initilized");
461     return NULL;
462     }
463    
464     /* ONLY if requesting for a username and if savebyname() is true
465     * PS: yes its kind of a hack, we will make a proper index file
466     */
467     if (accname && prefs_get_savebyname()) {
468     pathname = xmalloc(strlen(accountsdir) + 1 + strlen(accname) + 1); /* dir + / + file + NUL */
469     sprintf(pathname, "%s/%s", accountsdir, accname);
470     if (access(pathname, F_OK)) /* if it doesn't exist */
471     {
472     xfree((void *) pathname);
473     return NULL;
474     }
475     return pathname;
476     }
477    
478     return NULL;
479     }
480    
481     static int file_cmp_info(t_storage_info * info1, t_storage_info * info2)
482     {
483     return strcmp((const char *) info1, (const char *) info2);
484     }
485    
486     static const char *file_escape_key(const char *key)
487     {
488     return key;
489     }
490    
491     static int file_load_clans(t_load_clans_func cb)
492     {
493     char const *dentry;
494     t_pdir *clandir;
495     char *pathname;
496     int clantag;
497     t_clan *clan;
498     FILE *fp;
499     char *clanname, *motd, *p;
500     char line[1024];
501     int cid, creation_time;
502     int member_uid, member_join_time;
503     char member_status;
504     t_clanmember *member;
505    
506     if (cb == NULL)
507     {
508     eventlog(eventlog_level_error, __FUNCTION__, "get NULL callback");
509     return -1;
510     }
511    
512     if (!(clandir = p_opendir(clansdir)))
513     {
514     eventlog(eventlog_level_error, __FUNCTION__, "unable to open clan directory \"%s\" for reading (p_opendir: %s)", clansdir, pstrerror(errno));
515     return -1;
516     }
517     eventlog(eventlog_level_trace, __FUNCTION__, "start reading clans");
518    
519     pathname = xmalloc(strlen(clansdir) + 1 + 4 + 1);
520     while ((dentry = p_readdir(clandir)) != NULL)
521     {
522     if (dentry[0] == '.')
523     continue;
524    
525     if (strlen(dentry) > 4)
526     {
527     eventlog(eventlog_level_error, __FUNCTION__, "found too long clan filename in clandir \"%s\"", dentry);
528     continue;
529     }
530    
531     sprintf(pathname, "%s/%s", clansdir, dentry);
532    
533     clantag = str_to_clantag(dentry);
534    
535     if ((fp = fopen(pathname, "r")) == NULL)
536     {
537     eventlog(eventlog_level_error, __FUNCTION__, "can't open clanfile \"%s\"", pathname);
538     continue;
539     }
540    
541     clan = xmalloc(sizeof(t_clan));
542     clan->clantag = clantag;
543    
544     if (!fgets(line, 1024, fp))
545     {
546     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: no first line");
547     xfree((void*)clan);
548     continue;
549     }
550    
551     clanname = line;
552     if (*clanname != '"')
553     {
554     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
555     xfree((void*)clan);
556     continue;
557     }
558     clanname++;
559     p = strchr(clanname, '"');
560     if (!p)
561     {
562     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
563     xfree((void*)clan);
564     continue;
565     }
566     *p = '\0';
567     if (strlen(clanname) >= CLAN_NAME_MAX)
568     {
569     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
570     xfree((void*)clan);
571     continue;
572     }
573    
574     p++;
575     if (*p != ',')
576     {
577     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
578     xfree((void*)clan);
579     continue;
580     }
581     p++;
582     if (*p != '"')
583     {
584     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
585     xfree((void*)clan);
586     continue;
587     }
588     motd = p + 1;
589     p = strchr(motd, '"');
590     if (!p)
591     {
592     eventlog(eventlog_level_error, __FUNCTION__, "invalid clan file: invalid first line");
593     xfree((void*)clan);
594     continue;
595     }
596     *p = '\0';
597    
598     if (sscanf(p + 1, ",%d,%d\n", &cid, &creation_time) != 2)
599     {
600     eventlog(eventlog_level_error, __FUNCTION__, "invalid first line in clanfile");
601     xfree((void*)clan);
602     continue;
603     }
604     clan->clanname = xstrdup(clanname);
605     clan->clan_motd = xstrdup(motd);
606     clan->clanid = cid;
607     clan->creation_time = (time_t) creation_time;
608     clan->created = 1;
609     clan->modified = 0;
610     clan->channel_type = prefs_get_clan_channel_default_private();
611    
612     eventlog(eventlog_level_trace, __FUNCTION__, "name: %s motd: %s clanid: %i time: %i", clanname, motd, cid, creation_time);
613    
614     clan->members = list_create();
615    
616     while (fscanf(fp, "%i,%c,%i\n", &member_uid, &member_status, &member_join_time) == 3)
617     {
618     member = xmalloc(sizeof(t_clanmember));
619     if (!(member->memberacc = accountlist_find_account_by_uid(member_uid)))
620     {
621     eventlog(eventlog_level_error, __FUNCTION__, "cannot find uid %u", member_uid);
622     xfree((void *) member);
623     continue;
624     }
625     member->status = member_status - '0';
626     member->join_time = member_join_time;
627     member->clan = clan;
628    
629     if ((member->status == CLAN_NEW) && (time(NULL) - member->join_time > prefs_get_clan_newer_time() * 3600))
630     {
631     member->status = CLAN_PEON;
632     clan->modified = 1;
633     }
634    
635     list_append_data(clan->members, member);
636    
637     account_set_clanmember(member->memberacc, member);
638     eventlog(eventlog_level_trace, __FUNCTION__, "added member: uid: %i status: %c join_time: %i", member_uid, member_status + '0', member_join_time);
639     }
640    
641     fclose(fp);
642    
643     cb(clan);
644    
645     }
646    
647     xfree((void *) pathname);
648    
649     if (p_closedir(clandir) < 0)
650     {
651     eventlog(eventlog_level_error, __FUNCTION__, "unable to close clan directory \"%s\" (p_closedir: %s)", clansdir, pstrerror(errno));
652     }
653     eventlog(eventlog_level_trace, __FUNCTION__, "finished reading clans");
654    
655     return 0;
656     }
657    
658     static int file_write_clan(void *data)
659     {
660     FILE *fp;
661     t_elem *curr;
662     t_clanmember *member;
663     char *clanfile;
664     t_clan *clan = (t_clan *) data;
665    
666     clanfile = xmalloc(strlen(clansdir) + 1 + 4 + 1);
667     sprintf(clanfile, "%s/%c%c%c%c", clansdir, clan->clantag >> 24, (clan->clantag >> 16) & 0xff, (clan->clantag >> 8) & 0xff, clan->clantag & 0xff);
668    
669     if ((fp = fopen(clanfile, "w")) == NULL)
670     {
671     eventlog(eventlog_level_error, __FUNCTION__, "can't open clanfile \"%s\"", clanfile);
672     xfree((void *) clanfile);
673     return -1;
674     }
675    
676     fprintf(fp, "\"%s\",\"%s\",%i,%i\n", clan->clanname, clan->clan_motd, clan->clanid, (int) clan->creation_time);
677    
678     LIST_TRAVERSE(clan->members, curr)
679     {
680     if (!(member = elem_get_data(curr)))
681     {
682     eventlog(eventlog_level_error, __FUNCTION__, "got NULL elem in list");
683     continue;
684     }
685     if ((member->status == CLAN_NEW) && (time(NULL) - member->join_time > prefs_get_clan_newer_time() * 3600))
686     member->status = CLAN_PEON;
687     fprintf(fp, "%i,%c,%u\n", account_get_uid(member->memberacc), member->status + '0', (unsigned) member->join_time);
688     }
689    
690     fclose(fp);
691     xfree((void *) clanfile);
692     return 0;
693     }
694    
695     static int file_remove_clan(int clantag)
696     {
697     char *tempname;
698    
699     tempname = xmalloc(strlen(clansdir) + 1 + 4 + 1);
700     sprintf(tempname, "%s/%c%c%c%c", clansdir, clantag >> 24, (clantag >> 16) & 0xff, (clantag >> 8) & 0xff, clantag & 0xff);
701     if (remove((const char *) tempname) < 0)
702     {
703     eventlog(eventlog_level_error, __FUNCTION__, "could not delete clan file \"%s\" (remove: %s)", (char *) tempname, pstrerror(errno));
704     xfree(tempname);
705     return -1;
706     }
707     xfree(tempname);
708     return 0;
709     }
710    
711     static int file_remove_clanmember(int uid)
712     {
713     return 0;
714     }
715    
716     static int file_load_teams(t_load_teams_func cb)
717     {
718     char const *dentry;
719     t_pdir *teamdir;
720     char *pathname;
721     unsigned int teamid;
722     t_team *team;
723     FILE *fp;
724     char * line;
725     unsigned int fteamid,lastgame;
726     unsigned char size;
727     char clienttag[5];
728     int i;
729    
730     if (cb == NULL)
731     {
732     eventlog(eventlog_level_error, __FUNCTION__, "get NULL callback");
733     return -1;
734     }
735    
736     if (!(teamdir = p_opendir(teamsdir)))
737     {
738     eventlog(eventlog_level_error, __FUNCTION__, "unable to open team directory \"%s\" for reading (p_opendir: %s)", teamsdir, pstrerror(errno));
739     return -1;
740     }
741     eventlog(eventlog_level_trace, __FUNCTION__, "start reading teams");
742    
743     pathname = xmalloc(strlen(teamsdir) + 1 + 8 + 1);
744     while ((dentry = p_readdir(teamdir)) != NULL)
745     {
746     if (dentry[0] == '.')
747     continue;
748    
749     if (strlen(dentry) != 8)
750     {
751     eventlog(eventlog_level_error, __FUNCTION__, "found invalid team filename in teamdir \"%s\"", dentry);
752     continue;
753     }
754    
755     sprintf(pathname, "%s/%s", teamsdir, dentry);
756    
757     teamid = (unsigned int)strtoul(dentry,NULL,16); // we use hexadecimal teamid as filename
758    
759     if ((fp = fopen(pathname, "r")) == NULL)
760     {
761     eventlog(eventlog_level_error, __FUNCTION__, "can't open teamfile \"%s\"", pathname);
762     continue;
763     }
764    
765     team = xmalloc(sizeof(t_team));
766     team->teamid = teamid;
767    
768     if (!(line = file_get_line(fp)))
769     {
770     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: file is empty");
771     goto load_team_failure;
772     }
773    
774     if (sscanf(line,"%u,%c,%4s,%u",&fteamid,&size,clienttag,&lastgame)!=4)
775     {
776     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: invalid number of arguments on first line");
777     goto load_team_failure;
778     }
779    
780     if (fteamid != teamid)
781     {
782     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: filename and stored teamid don't match");
783     goto load_team_failure;
784     }
785    
786     size -='0';
787     if ((size<2) || (size>4))
788     {
789     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: invalid team size");
790     goto load_team_failure;
791     }
792     team->size = size;
793    
794     if (!(tag_check_client(team->clienttag = tag_str_to_uint(clienttag))))
795     {
796     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: invalid clienttag");
797     goto load_team_failure;
798     }
799     team->lastgame = (time_t)lastgame;
800    
801     if (!(line= file_get_line(fp)))
802     {
803     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: missing 2nd line");
804     goto load_team_failure;
805     }
806    
807     if (sscanf(line,"%u,%u,%u,%u",&team->teammembers[0],&team->teammembers[1],&team->teammembers[2],&team->teammembers[3])!=4)
808     {
809     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: invalid number of arguments on 2nd line");
810     goto load_team_failure;
811     }
812    
813     for (i=0; i<MAX_TEAMSIZE;i++)
814     {
815     if (i<size)
816     {
817     if ((team->teammembers[i]==0))
818     {
819     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: too few members");
820     goto load_team_failure;
821     }
822     }
823     else
824     {
825     if ((team->teammembers[i]!=0))
826     {
827     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: too many members");
828     goto load_team_failure;
829     }
830    
831     }
832     team->members[i] = NULL;
833     }
834    
835     if (!(line= file_get_line(fp)))
836     {
837     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: missing 3rd line");
838     goto load_team_failure;
839     }
840    
841     if (sscanf(line,"%d,%d,%d,%d,%d",&team->wins,&team->losses,&team->xp,&team->level,&team->rank)!=5)
842     {
843     eventlog(eventlog_level_error,__FUNCTION__,"invalid team file: invalid number of arguments on 3rd line");
844     goto load_team_failure;
845     }
846    
847     eventlog(eventlog_level_trace,__FUNCTION__,"succesfully loaded team %s",dentry);
848     cb(team);
849    
850     goto load_team_success;
851     load_team_failure:
852     xfree((void*)team);
853     eventlog(eventlog_level_error,__FUNCTION__,"error while reading file \"%s\"",dentry);
854    
855     load_team_success:
856    
857     file_get_line(NULL); // clear file_get_line buffer
858     fclose(fp);
859    
860    
861     }
862    
863     xfree((void *) pathname);
864    
865     if (p_closedir(teamdir) < 0)
866     {
867     eventlog(eventlog_level_error, __FUNCTION__, "unable to close team directory \"%s\" (p_closedir: %s)", teamsdir, pstrerror(errno));
868     }
869     eventlog(eventlog_level_trace, __FUNCTION__, "finished reading teams");
870    
871     return 0;
872     }
873    
874     static int file_write_team(void *data)
875     {
876     FILE *fp;
877     char *teamfile;
878     t_team *team = (t_team *) data;
879    
880     teamfile = xmalloc(strlen(teamsdir) + 1 + 8 + 1);
881     sprintf(teamfile, "%s/%08x", teamsdir, team->teamid);
882    
883     if ((fp = fopen(teamfile, "w")) == NULL)
884     {
885     eventlog(eventlog_level_error, __FUNCTION__, "can't open teamfile \"%s\"", teamfile);
886     xfree((void *) teamfile);
887     return -1;
888     }
889    
890     fprintf(fp,"%u,%c,%s,%u\n",team->teamid,team->size+'0',clienttag_uint_to_str(team->clienttag),(unsigned int)team->lastgame);
891     fprintf(fp,"%u,%u,%u,%u\n",team->teammembers[0],team->teammembers[1],team->teammembers[2],team->teammembers[3]);
892     fprintf(fp,"%d,%d,%d,%d,%d\n",team->wins,team->losses,team->xp,team->level,team->rank);
893    
894     fclose(fp);
895     xfree((void *) teamfile);
896    
897     return 0;
898     }
899    
900     static int file_remove_team(unsigned int teamid)
901     {
902    
903     char *tempname;
904    
905     tempname = xmalloc(strlen(clansdir) + 1 + 8 + 1);
906     sprintf(tempname, "%s/%08x", clansdir, teamid);
907     if (remove((const char *) tempname) < 0)
908     {
909     eventlog(eventlog_level_error, __FUNCTION__, "could not delete team file \"%s\" (remove: %s)", (char *) tempname, pstrerror(errno));
910     xfree(tempname);
911     return -1;
912     }
913     xfree(tempname);
914    
915     return 0;
916     }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1