diff --git a/checkin_notes b/checkin_notes
index e5a2cceff4..cb05de0d5d 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -3043,3 +3043,24 @@ David Jan 29 2003
sched/
db_dump.C (new)
Makefile.in
+
+David Jan 30 2003
+ - continued work on db_dump
+ - added doc for db_dump
+ - added create_time field to team table
+
+ db/
+ db.h
+ db_mysql.C
+ mysql_util.C,h
+ doc/
+ db_dump.html (new)
+ stripchart.html (new)
+ stripchart_data.html (new)
+ html_user/
+ team_create_action.php
+ lib/
+ util.C,h
+ sched/
+ Makefile.in
+ db_dump.C
diff --git a/db/db.h b/db/db.h
index 6f132c4b2f..7fab1c995a 100644
--- a/db/db.h
+++ b/db/db.h
@@ -122,6 +122,7 @@ struct USER {
struct TEAM {
int id;
+ unsigned int create_time;
int userid; // User ID of team founder
char name[256];
char name_lc[256]; // Team name in lowercase (used for searching)
@@ -129,8 +130,10 @@ struct TEAM {
int type; // Team type (see above)
char name_html[256];
char description[MAX_BLOB_SIZE];
- int nusers;
+ int nusers; // UNDEFINED BY DEFAULT
char country[256];
+ double total_credit; // UNDEFINED BY DEFAULT
+ double expavg_credit; // UNDEFINED BY DEFAULT
};
struct HOST {
@@ -322,18 +325,33 @@ extern int db_app_version_enum(APP_VERSION&);
extern int db_user_new(USER&);
extern int db_user(int, USER&);
extern int db_user_update(USER&);
+extern int db_user_count(int&);
extern int db_user_lookup_auth(USER&);
extern int db_user_lookup_email_addr(USER&);
+extern int db_user_enum_id(USER&);
+extern int db_user_enum_total_credit(USER&);
+extern int db_user_enum_expavg_credit(USER&);
+extern int db_user_enum_teamid(USER&);
extern int db_team(int, TEAM&);
extern int db_team_new(TEAM&);
extern int db_team_update(TEAM&);
+extern int db_team_count(int&);
extern int db_team_lookup_name(TEAM&);
extern int db_team_lookup_name_lc(TEAM&);
+extern int db_team_enum(TEAM&);
+extern int db_team_enum_id(TEAM&);
+extern int db_team_enum_total_credit(TEAM&);
+extern int db_team_enum_expavg_credit(TEAM&);
extern int db_host_new(HOST& p);
extern int db_host(int, HOST&);
extern int db_host_update(HOST&);
+extern int db_host_count(int&);
+extern int db_host_enum_id(HOST&);
+extern int db_host_enum_userid(HOST&);
+extern int db_host_enum_total_credit(HOST&);
+extern int db_host_enum_expavg_credit(HOST&);
extern int db_workunit_new(WORKUNIT& p);
extern int db_workunit(int id, WORKUNIT&);
diff --git a/db/db_mysql.C b/db/db_mysql.C
index 5322dd0736..4e94ae8e8b 100644
--- a/db/db_mysql.C
+++ b/db/db_mysql.C
@@ -173,11 +173,12 @@ void BOINC_MYSQL_DB::struct_to_str(void* vp, char* q, int type) {
case TYPE_TEAM:
tp = (TEAM*)vp;
sprintf(q,
- "id=%d, userid=%d, name='%s', "
+ "id=%d, create_time=%d, userid=%d, name='%s', "
"name_lc='%s', url='%s', "
"type=%d, name_html='%s', description='%s', nusers=%d, "
- "country='%s'",
+ "country='%s', total_credit=%f, expavg_credit=%f",
tp->id,
+ tp->create_time,
tp->userid,
tp->name,
tp->name_lc,
@@ -186,7 +187,9 @@ void BOINC_MYSQL_DB::struct_to_str(void* vp, char* q, int type) {
tp->name_html,
tp->description,
tp->nusers,
- tp->country
+ tp->country,
+ tp->total_credit,
+ tp->expavg_credit
);
break;
case TYPE_HOST:
@@ -352,6 +355,7 @@ void BOINC_MYSQL_DB::row_to_struct(MYSQL_ROW& r, void* vp, int type) {
tp = (TEAM*)tp;
memset(tp, 0, sizeof(TEAM));
tp->id = atoi(r[i++]);
+ tp->create_time = atoi(r[i++]);
tp->userid = atoi(r[i++]);
strcpy2(tp->name, r[i++]);
strcpy2(tp->name_lc, r[i++]);
@@ -360,6 +364,8 @@ void BOINC_MYSQL_DB::row_to_struct(MYSQL_ROW& r, void* vp, int type) {
strcpy2(tp->description, r[i++]);
tp->nusers = atoi(r[i++]);
strcpy2(tp->country, r[i++]);
+ tp->total_credit = atof(r[i++]);
+ tp->expavg_credit = atof(r[i++]);
break;
case TYPE_HOST:
hp = (HOST*)vp;
@@ -557,6 +563,10 @@ int db_user_lookup_auth(USER& p) {
return boinc_db.db_lookup(&p, TYPE_USER, buf);
}
+int db_user_count(int& n) {
+ return boinc_db.db_count(&n, "*", TYPE_USER);
+}
+
int db_user_lookup_email_addr(USER& p) {
char buf[256];
@@ -564,6 +574,30 @@ int db_user_lookup_email_addr(USER& p) {
return boinc_db.db_lookup(&p, TYPE_USER, buf);
}
+int db_user_enum_id(USER& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM, "order by id");
+}
+int db_user_enum_total_credit(USER& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM, "order by total_credit desc");
+}
+
+int db_user_enum_expavg_credit(USER& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_USER, "order by expavg_credit desc");
+}
+
+int db_user_enum_teamid(USER& p) {
+ static ENUM e;
+ char buf[256];
+
+ if (!e.active) {
+ sprintf(buf, "where teamid=%d", p.teamid);
+ }
+ return boinc_db.db_enum(e, &p, TYPE_USER, buf);
+}
+
////////// TEAM /////////
int db_team(int i, TEAM& p) {
@@ -578,6 +612,10 @@ int db_team_update(TEAM& p) {
return boinc_db.db_update(&p, TYPE_TEAM);
}
+int db_team_count(int& n) {
+ return boinc_db.db_count(&n, "*", TYPE_TEAM);
+}
+
int db_team_lookup_name(TEAM& p) {
char buf[256];
@@ -592,6 +630,26 @@ int db_team_lookup_name_lc(TEAM& p) {
return boinc_db.db_lookup(&p, TYPE_TEAM, buf);
}
+int db_team_enum(TEAM& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM);
+}
+
+int db_team_enum_id(TEAM& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM, "order by id");
+}
+
+int db_team_enum_total_credit(TEAM& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM, "order by total_credit desc");
+}
+
+int db_team_enum_expavg_credit(TEAM& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_TEAM, "order by expavg_credit desc");
+}
+
////////// HOST /////////
int db_host_new(HOST& p) {
@@ -602,10 +660,39 @@ int db_host(int i, HOST& p) {
return boinc_db.db_lookup_id(i, &p, TYPE_HOST);
}
+int db_host_count(int& n) {
+ return boinc_db.db_count(&n, "*", TYPE_HOST);
+}
+
int db_host_update(HOST& p) {
return boinc_db.db_update(&p, TYPE_HOST);
}
+int db_host_enum_id(HOST& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_HOST, "order by id");
+}
+
+int db_host_enum_userid(HOST& p) {
+ static ENUM e;
+ char buf[256];
+
+ if (!e.active) {
+ sprintf(buf, "where userid=%d", p.userid);
+ }
+ return boinc_db.db_enum(e, &p, TYPE_HOST, buf);
+}
+
+int db_host_enum_total_credit(HOST& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_HOST, "order by total_credit desc");
+}
+
+int db_host_enum_expavg_credit(HOST& p) {
+ static ENUM e;
+ return boinc_db.db_enum(e, &p, TYPE_HOST, "order by expavg_credit desc");
+}
+
////////// WORKUNIT /////////
int db_workunit_new(WORKUNIT& p) {
diff --git a/db/mysql_util.C b/db/mysql_util.C
index e30840821b..355f7d4853 100644
--- a/db/mysql_util.C
+++ b/db/mysql_util.C
@@ -192,7 +192,8 @@ int MYSQL_DB::db_query_int(int* ip, char* query) {
int MYSQL_DB::db_count(int* np, char* what, int type, char* clause) {
char buf[MAX_QUERY_LEN];
- sprintf(buf, "select count(%s) from %s %s", what, table_name[type], clause);
+ sprintf(buf, "select count(%s) from %s ", what, table_name[type]);
+ if (clause) strcat(buf, clause);
return db_query_int(np, buf);
}
diff --git a/db/mysql_util.h b/db/mysql_util.h
index d73905fcf9..788cf66a4f 100644
--- a/db/mysql_util.h
+++ b/db/mysql_util.h
@@ -49,6 +49,6 @@ public:
int db_enum(ENUM&, void*, int, char* clause=0, int limit=0);
int db_enum_field(ENUM&, int, char*, char*);
int db_query_int(int*, char*);
- int db_count(int*, char*, int, char*);
+ int db_count(int*, char*, int, char* clause=0);
int db_query(char*);
};
diff --git a/db/schema.sql b/db/schema.sql
index 5b6f5a7812..8988904c33 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -49,20 +49,21 @@ create table user (
expavg_time double not null,
global_prefs blob,
project_prefs blob,
- teamid integer not null,
+ teamid integer not null,
primary key (id)
);
create table team (
- id integer not null auto_increment,
- userid integer not null,
- name varchar(254) not null,
- name_lc varchar(254),
- url varchar(254),
- type integer not null,
- name_html varchar(254),
+ id integer not null auto_increment,
+ create_time integer not null,
+ userid integer not null,
+ name varchar(254) not null,
+ name_lc varchar(254),
+ url varchar(254),
+ type integer not null,
+ name_html varchar(254),
description blob,
- nusers integer not null,
+ nusers integer not null, /* temp */
country varchar(254),
total_credit double not null, /* temp */
expavg_credit double not null, /* temp */
diff --git a/doc/stripchart.html b/doc/stripchart.html
new file mode 100644
index 0000000000..f7d657ec2b
--- /dev/null
+++ b/doc/stripchart.html
@@ -0,0 +1,25 @@
+
Stripcharts
+Stripcharts
+
+Goals
+
+Stripcharts is a system for recording and displaying
+time-varying system load and performance information.
+The basic idea:
+
+
+- A set of scripts, run periodically using crontab,
+record performance metrics
+(CPU load, network connection rates, queue lengths, etc.)
+as time-stamped entries in log files.
+
- A web interface lets you generate graphs of
+combinations of these quantities,
+over whatever time scale you want.
+
+Looking at these graphs can be a major help in tracking
+down problems in complex server systems.
+
+
+Stripcharts is independent of BOINC,
+but it's especially helpful for diagnosing performance
+problems in BOINC servers.
diff --git a/doc/stripchart_data.html b/doc/stripchart_data.html
new file mode 100644
index 0000000000..026c8c1f73
--- /dev/null
+++ b/doc/stripchart_data.html
@@ -0,0 +1,13 @@
+
Stripchar data
+Stripchar data
+
+
+- CPU load
+
- number of users
+
- number of results
+
- number of results sent
+
- number of results returned
+
- disk usage
+
- connections/second
+
- network bandwidth
+
diff --git a/html/user/team_create_action.php b/html/user/team_create_action.php
index fe0f91958c..1155b1393e 100644
--- a/html/user/team_create_action.php
+++ b/html/user/team_create_action.php
@@ -16,8 +16,9 @@
echo "You must specify a name for your team.";
} else {
$query = sprintf(
- "insert into team (userid, name, name_lc, url, type, name_html, description, nusers) values(%d, '%s', '%s', '%s', %d, '%s', '%s', %d)",
+ "insert into team (userid, create_time, name, name_lc, url, type, name_html, description, nusers) values(%d, '%s', '%s', '%s', %d, '%s', '%s', %d)",
$user->id,
+ time(),
$HTTP_POST_VARS["name"],
strtolower($HTTP_POST_VARS["name"]),
$HTTP_POST_VARS["url"],
@@ -69,6 +70,5 @@
page_tail();
}
}
-}
+ }
?>
-
diff --git a/lib/util.C b/lib/util.C
index 9d167e071b..0ea9a32697 100755
--- a/lib/util.C
+++ b/lib/util.C
@@ -140,7 +140,7 @@ int parse_command_line(char* p, char** argv) {
} else {
if (space) {
*pp++ = p;
- argc++;
+ argc++;
space = false;
}
}
@@ -180,3 +180,62 @@ int lock_file(char* filename) {
double drand() {
return (double)rand()/(double)RAND_MAX;
}
+
+static char x2c(char *what) {
+ register char digit;
+
+ digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
+ digit *= 16;
+ digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
+ return(digit);
+}
+
+static void c2x(char *what) {
+ char buf[3];
+ char num = atoi(what);
+ char d1 = num / 16;
+ char d2 = num % 16;
+ int abase1, abase2;
+ if (d1 < 10) abase1 = 48;
+ else abase1 = 55;
+ if (d2 < 10) abase2 = 48;
+ else abase2 = 55;
+ buf[0] = d1+abase1;
+ buf[1] = d2+abase2;
+ buf[2] = 0;
+
+ strcpy(what, buf);
+}
+
+void unescape_url(char *url) {
+ register int x,y;
+
+ for(x=0,y=0;url[y];++x,++y) {
+ if((url[x] = url[y]) == '%') {
+ url[x] = x2c(&url[y+1]);
+ y+=2;
+ }
+ }
+ url[x] = '\0';
+}
+
+void escape_url(char *in, char*out) {
+ int x, y;
+ for (x=0, y=0; in[x]; ++x) {
+ if (isalnum(in[x])) {
+ out[y] = in[x];
+ ++y;
+ } else {
+ out[y] = '%';
+ ++y;
+ out[y] = 0;
+ char buf[256];
+ sprintf(buf, "%d", (char)in[x]);
+ c2x(buf);
+ strcat(out, buf);
+ y += 2;
+ }
+ }
+ out[y] = 0;
+}
+
diff --git a/lib/util.h b/lib/util.h
index a910c42c95..e5a34af1d2 100755
--- a/lib/util.h
+++ b/lib/util.h
@@ -25,6 +25,8 @@ extern void boinc_sleep( int seconds );
extern int parse_command_line( char *, char ** );
extern int lock_file(char*);
extern double drand();
+extern void unescape_url(char *url);
+extern void escape_url(char *in, char*out);
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
diff --git a/sched/Makefile.in b/sched/Makefile.in
index ad94c66cfa..9f6c5e2f18 100644
--- a/sched/Makefile.in
+++ b/sched/Makefile.in
@@ -110,8 +110,11 @@ RESULT_RETRY_OBJS = \
../RSAEuro/source/rsaeuro.a
DB_DUMP_OBJS = \
- ../db/db_mysql.fcgi.o \
- ../db/mysql_util.fcgi.o \
+ ../db/db_mysql.o \
+ ../db/mysql_util.o \
+ ../lib/parse.o \
+ ../lib/util.o \
+ config.o \
db_dump.o
FCGI_OBJS = \
@@ -176,6 +179,9 @@ file_deleter: $(FILE_DELETER_OBJS)
assimilator: $(ASSIMILATOR_OBJS)
$(CC) $(ASSIMILATOR_OBJS) $(MYSQL_LIBS) $(CLIBS) -o assimilator
+db_dump: $(DB_DUMP_OBJS)
+ $(CC) $(DB_DUMP_OBJS) $(MYSQL_LIBS) $(CLIBS) -o db_dump
+
fcgi: $(FCGI_OBJS)
$(CC) $(FCGI_OBJS) $(MYSQL_LIBS) $(CLIBS) $(FCGI_LIBS) \
-o fcgi
diff --git a/sched/db_dump.C b/sched/db_dump.C
index 827438578b..be650bc990 100644
--- a/sched/db_dump.C
+++ b/sched/db_dump.C
@@ -17,31 +17,214 @@
// Contributor(s):
//
-// db_dump: dump parts of database in XML form
+// db_dump: dump database views in XML format
+//
+// usage: db_dump [-dir path] [-update_teams]
// files:
+// NOTE: the goal is to make the full DB available (view *_id files)
+// to those who want it,
+// while allowing those who want to see only a particular row,
+// or the highest-ranked rows, to get this info with limited transfer
//
-// team_totalcredit_N.xml N = 0, 1, ...
-// team_avgcredit_N.xml N = 0, 1, ...
-// user_totalcredit_N.xml N = 0, 1, ...
-// user_avgcredit_N.xml N = 0, 1, ...
-// user_team_N.xml N = team ID
-// host_user_N.xml N = user ID
-// host_totalcredit_N.xml N = 0, 1, ...
-// host_avgcredit_N.xml N = 0, 1, ...
+//
+// tables.xml
+// for each table (team, user, host):
+// total number of records
+// number of records per file for summary files
+// number of records per file for detailed files
+// team_total_credit_N.xml
+// list of teams by decreasing total credit (summary)
+// team_expavg_credit_N.xml
+// team_id_N.xml
+// teams by ID (detailed, including list of user summaries)
+// user_total_credit_N.xml
+// list of users by total credit (summary)
+// user_expavg_credit_N.xml
+// user_id_N.xml
+// users by ID (detailed, including list of host summaries)
+// host_total_credit_N.xml
+// hosts by decreasing total credit (summary)
+// host_expavg_credit_N.xml
+// host_id_N.xml
+// hosts by ID (detailed)
+
+// NOTE: for now we're using verbose XML tag names.
+// We may change to short tag names to save bandwidth.
#include
+#include
#include "db.h"
+#include "util.h"
#include "config.h"
-void write_team(TEAM& team, FILE* f) {
+#define NRECS_PER_FILE_SUMMARY 1000
+#define NRECS_PER_FILE_DETAIL 100
+
+// fill in the nusers, total_credit and expavg_credit fields
+// of the team table.
+// This may take a while; don't do it often
+//
+int update_teams() {
+ TEAM team;
+ USER user;
+ int retval;
+
+ while (!db_team_enum(team)) {
+ team.nusers = 0;
+ team.total_credit = 0;
+ team.expavg_credit = 0;
+ user.teamid = team.id;
+ while (!db_user_enum_teamid(user)) {
+ team.nusers++;
+ team.total_credit += user.total_credit;
+ team.expavg_credit += user.expavg_credit;
+ }
+ retval = db_team_update(team);
+ if (retval) return retval;
+ }
+ return 0;
+}
+
+void write_host(HOST& host, FILE* f, bool detail) {
fprintf(f,
- ""
+ "\n"
+ " %d\n"
+ " %d\n"
+ " %f\n"
+ " %f\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n",
+ host.id,
+ host.userid,
+ host.total_credit,
+ host.expavg_credit,
+ host.p_vendor,
+ host.p_model,
+ host.os_name,
+ host.os_version
+ );
+ if (detail) {
+ fprintf(f,
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n"
+ " %f\n",
+ host.create_time,
+ host.timezone,
+ host.p_ncpus,
+ host.p_fpops,
+ host.p_iops,
+ host.p_membw,
+ host.m_nbytes,
+ host.m_cache,
+ host.m_swap,
+ host.d_total,
+ host.d_free,
+ host.n_bwup,
+ host.n_bwdown
+ );
+ }
+ fprintf(f,
+ "\n"
);
}
-void team_totalcredit() {
+void write_user(USER& user, FILE* f, bool detail) {
+ HOST host;
+ fprintf(f,
+ "\n"
+ " %d\n"
+ " %s\n"
+ " %f\n"
+ " %f\n"
+ " %d\n",
+ user.id,
+ user.name,
+ user.total_credit,
+ user.expavg_credit,
+ user.teamid
+ );
+ if (detail) {
+ host.userid = user.id;
+ while (!db_host_enum_userid(host)) {
+ write_host(host, f, false);
+ }
+ }
+ fprintf(f,
+ "\n"
+ );
+}
+
+void write_team(TEAM& team, FILE* f, bool detail) {
+ USER user;
+ char buf[MAX_BLOB_SIZE*2];
+
+ fprintf(f,
+ "\n"
+ " %d\n"
+ " %s\n"
+ " %f\n"
+ " %f\n"
+ " %d\n",
+ team.id,
+ team.name,
+ team.total_credit,
+ team.expavg_credit,
+ team.nusers
+ );
+ if (detail) {
+ fprintf(f,
+ " %d\n",
+ team.create_time
+ );
+ if (strlen(team.url)) {
+ fprintf(f,
+ " %s\n",
+ team.url
+ );
+ }
+ if (strlen(team.name_html)) {
+ escape_url(team.name_html, buf);
+ fprintf(f,
+ "%s\n",
+ buf
+ );
+ }
+ if (strlen(team.description)) {
+ escape_url(team.description, buf);
+ fprintf(f,
+ "%s\n",
+ buf
+ );
+ }
+ fprintf(f,
+ " %s\n",
+ team.country
+ );
+ user.teamid = team.id;
+ while (!db_user_enum_teamid(user)) {
+ write_user(user, f, false);
+ }
+ }
+ fprintf(f,
+ "\n"
+ );
+}
+
+void team_total_credit() {
TEAM team;
FILE* f;
int nfile=0, nrec;
@@ -49,24 +232,248 @@ void team_totalcredit() {
while (!db_team_enum_total_credit(team)) {
if (!f) {
- sprintf(buf, "team_totalcredit_%d", nf);
+ sprintf(buf, "team_total_credit_%d", nfile);
f = fopen(buf, "w");
- nf++;
+ nfile++;
nrec = 0;
}
- write_team(team, f);
+ write_team(team, f, false);
nrec++;
- if (nrec == NRECS_PER_FILE) {
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
fclose(f);
f = 0;
}
}
}
-main() {
- CONFIG config;
- int retval;
+void team_expavg_credit() {
+ TEAM team;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+ while (!db_team_enum_expavg_credit(team)) {
+ if (!f) {
+ sprintf(buf, "team_expavg_credit_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_team(team, f, false);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void team_id() {
+ TEAM team;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_team_enum_id(team)) {
+ if (!f) {
+ sprintf(buf, "team_id_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_team(team, f, true);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_DETAIL) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void user_total_credit() {
+ USER user;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_user_enum_total_credit(user)) {
+ if (!f) {
+ sprintf(buf, "user_total_credit_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_user(user, f, false);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void user_expavg_credit() {
+ USER user;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_user_enum_expavg_credit(user)) {
+ if (!f) {
+ sprintf(buf, "user_expavg_credit_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_user(user, f, false);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void user_id() {
+ USER user;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_user_enum_id(user)) {
+ if (!f) {
+ sprintf(buf, "user_id_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_user(user, f, true);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_DETAIL) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void host_total_credit() {
+ HOST host;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_host_enum_total_credit(host)) {
+ if (!f) {
+ sprintf(buf, "host_total_credit_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_host(host, f, false);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+void host_expavg_credit() {
+ HOST host;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_host_enum_expavg_credit(host)) {
+ if (!f) {
+ sprintf(buf, "host_expavg_credit_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_host(host, f, false);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_SUMMARY) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+void host_id() {
+ HOST host;
+ FILE* f;
+ int nfile=0, nrec;
+ char buf[256];
+
+ while (!db_host_enum_id(host)) {
+ if (!f) {
+ sprintf(buf, "host_id_%d", nfile);
+ f = fopen(buf, "w");
+ nfile++;
+ nrec = 0;
+ }
+ write_host(host, f, true);
+ nrec++;
+ if (nrec == NRECS_PER_FILE_DETAIL) {
+ fclose(f);
+ f = 0;
+ }
+ }
+}
+
+int tables_file() {
+ int nusers, nteams, nhosts;
+ int retval;
+ FILE* f;
+
+ f = fopen("tables.xml", "w");
+ if (!f) return -1;
+ retval = db_user_count(nusers);
+ if (retval) return retval;
+ retval = db_team_count(nteams);
+ if (retval) return retval;
+ retval = db_host_count(nhosts);
+ if (retval) return retval;
+ fprintf(f,
+ "\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ " %d\n"
+ "\n",
+ nusers,
+ NRECS_PER_FILE_SUMMARY,
+ NRECS_PER_FILE_DETAIL,
+ nteams,
+ NRECS_PER_FILE_SUMMARY,
+ NRECS_PER_FILE_DETAIL,
+ nhosts,
+ NRECS_PER_FILE_SUMMARY,
+ NRECS_PER_FILE_DETAIL
+ );
+ fclose(f);
+ return 0;
+}
+
+int main(int argc, char** argv) {
+ CONFIG config;
+ int retval, i;
+ bool do_update_teams = false;
+ char dir[256];
+
+ strcpy(dir, "");
+ for (i=1; i