1 Add support for logging daemon messages to an SQL database.
3 After applying this patch you'll need to run autoconf and autoheader to
4 generate updated versions of "configure" and "config.h.in".
6 You'll need to run configure with the --with-ODBC option in order for the
7 extended features to be active.
9 Patch provided by Steve Sether.
11 (Tweaked by Wayne Davison for rsync-style purposes but not compiled, so if the
12 dblog.c file has a compile problem, it's probably my fault...)
15 --- README-ODBC 2004-02-13 17:08:33.000000000 -0800
16 +++ README-ODBC 2004-04-07 22:42:28.000000000 -0700
18 +This patch adds the following options:
21 +If set to True, rsync will attempt to connect to
22 +the specified datasource and write to the named tables.
26 +"database datasource"
27 +Specifies the name of the ODBC data source to use.
30 +The username to use when connecting to the database.
33 +The password to use when connecting to the database.
35 +"transfer table name"
36 +The name of the transfer table to log to.
37 +This table contains individual filenames, file sizes, bytes transferred, checksum bytes transferred, operation (send or receive), and a timestamp.
40 +The name of the session table to log to.
41 +This table contains the username, module name, module path, ip address, process ID, and a timestamp.
44 +The name of the exit table to log to.
45 +This table contains the total bytes read, total bytes written, total size
46 +of all files, error code, line the error occured at, file the error occured at
47 +and the text of the error. (most of which will be blank if the program exited normally).
51 +Different databases use different methods to get a unique identifier.
52 +Some databases support sequence objects, and use various forms of the
53 +nextval command to retrieve a unique identifier from it. Other databases
54 +support an autonumber field, and support different methds of retrieving
55 +the ID used in the last insert. Valid values for this option are:
58 + uses the syntax of nextval for PostgreSQL databases
61 + uses the syntax of nextval for Oracle databases
64 + uses the syntax of nextval for DB2 databases
67 + uses the last_insert_id() command for the MySQL databases
70 + uses the @@IDENTITY command for Sybase databases
73 + Define your own method to get a unique identifier. See the
74 + "custom unique id select", and the "get custom id before select"
79 +If your database supports sequences, list the name of the sequence to use
80 +for the session unique identifier.
82 +"custom unique id select"
83 +Only used if you specify the custom method in "unique id method". This
84 +is a SQL statement to be executed to get a unique ID. This SQL
85 +statement must return one column with the unique ID to use for
86 +the session ID. Should be used in concert with the "get custom
87 +id before select" parameter.
89 +"get custom id before insert"
90 +This parameter is ignored unless the "unique id method" is set to custom.
91 +If set to true, the "custom unique id select" statement will
92 +be executed BEFORE the session row is inserted into the database.
93 +(as is done when a sequence is used for unique IDs).
94 +If False the statement will be executed after the session
95 +row is inserted (as is done when the session ID is automatically generates
98 --- Makefile.in 10 Feb 2004 17:06:11 -0000 1.98
99 +++ Makefile.in 8 Apr 2004 05:56:31 -0000
101 zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
102 zlib/zutil.o zlib/adler32.o
103 OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
104 - main.o checksum.o match.o syscall.o log.o backup.o
105 + main.o checksum.o match.o syscall.o log.o backup.o @EXTRA_OBJECT@
106 OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
107 fileio.o batch.o clientname.o
108 OBJS3=progress.o pipe.o
109 --- cleanup.c 27 Jan 2004 08:14:33 -0000 1.21
110 +++ cleanup.c 8 Apr 2004 05:56:31 -0000
112 code = RERR_VANISHED;
115 - if (code) log_exit(code, file, line);
117 + log_exit(code, file, line);
119 + db_log_exit(code,file,line);
124 rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
125 --- clientserver.c 14 Apr 2004 23:33:34 -0000 1.121
126 +++ clientserver.c 15 Apr 2004 18:51:14 -0000
128 exclude_path_prefix = NULL;
138 rprintf(FINFO,"rsync %s %s from %s@%s (%s)\n",
140 request, auth_user, host, addr);
145 rprintf(FINFO,"rsync %s %s from %s (%s)\n",
147 --- configure.in 9 Apr 2004 18:09:16 -0000 1.190
148 +++ configure.in 15 Apr 2004 18:51:14 -0000
150 [ --with-rsync-path=PATH set default --rsync-path to PATH (default: rsync)],
151 [ RSYNC_PATH="$with_rsync_path" ],
152 [ RSYNC_PATH="rsync" ])
154 + [ --with-ODBC compile in support for ODBC database logging])
156 AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
159 if test x"$with_included_popt" != x"yes"
161 AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
164 +if test x"$with_ODBC" = x"yes"
166 + AC_CHECK_HEADERS(sql.h sqlext.h sqltypes.h)
167 + AC_CHECK_LIB(odbc,SQLExecDirect)
168 + EXTRA_OBJECT="$EXTRA_OBJECT dblog.o"
169 + AC_SUBST(EXTRA_OBJECT)
172 AC_MSG_CHECKING([whether to use included libpopt])
173 --- dblog.c 2004-02-13 17:08:33.000000000 -0800
174 +++ dblog.c 2004-04-07 23:18:56.000000000 -0700
177 + * ODBC Database logging functions
179 + * Written by Steve Sether, April 2004
180 + * steve@vellmont.com
188 +#ifdef HAVE_ODBC_SQL_H
189 +#include <odbc/sql.h>
193 +#ifdef HAVE_SQLEXT_H
196 +#ifdef HAVE_ODBC_SQLEXT_H
197 +#include <odbc/sqlext.h>
201 +#ifdef HAVE_SQLTYPES_H
202 +#include <sqltypes.h>
204 +#ifdef HAVE_ODBC_SQLTYPES_H
205 +#include <odbc/sqltypes.h>
209 +SQLHENV db_environ_handle; /* Handle ODBC environment */
210 +long result; /* result of functions */
211 +SQLHDBC db_handle= NULL; /* database connection handle */
212 +SQLHSTMT sql_statement_handle; /* SQL statement handle */
213 +extern int am_sender;
214 +extern char *auth_user;
215 +extern int module_id;
217 +char sql_status[10]; /* Status SQL */
218 +SQLINTEGER V_OD_err, V_OD_rowanz, V_OD_id;
219 +SQLSMALLINT V_OD_mlen, V_OD_colanz;
220 +char V_OD_msg[200], V_OD_buffer[200];
221 +SQLINTEGER session_id;
224 +/* This function simply removes invalid characters from the SQL statement
225 + * to prevent SQL injection attacks. */
226 +char *sanitizeSql(const char *input)
231 + if (strlen(input) > ((~(unsigned int)0)>>1)-3)
233 + if (!(out = ptr = new_array(char, strlen(input) * 2 + 1)))
236 + for (c = input; *c; c++) {
267 +void db_log_open(void)
269 + if (lp_database_logging(module_id)) {
270 + if (db_handle == NULL) {
271 + /* get ODBC environment handle */
272 + result = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&db_environ_handle);
273 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
274 + rprintf(FERROR, "Error: couldn't get database environment handle\n");
278 + /* Setting database enviroment */
279 + result = SQLSetEnvAttr(db_environ_handle, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
280 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
281 + rprintf(FERROR, "Error: couldn't set database environment.\n");
282 + SQLFreeHandle(SQL_HANDLE_ENV, db_environ_handle);
283 + db_environ_handle = NULL;
287 + /* Get a database handle */
288 + result = SQLAllocHandle(SQL_HANDLE_DBC, db_environ_handle, &db_handle);
289 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
290 + rprintf(FERROR, "Error: couldn't allocate database handle\n");
291 + SQLFreeHandle(SQL_HANDLE_ENV, db_environ_handle);
292 + db_environ_handle = NULL;
296 + /* Set connection attributes */
297 + SQLSetConnectAttr(db_handle, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
299 + /* Connect to the database. */
300 + result = SQLConnect(db_handle, (SQLCHAR*) lp_database_datasource(module_id), SQL_NTS,
301 + (SQLCHAR*) lp_database_username(module_id), SQL_NTS,
302 + (SQLCHAR*) lp_database_password(module_id), SQL_NTS);
304 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
305 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1,
306 + sql_status, &V_OD_err,V_OD_msg,100,&V_OD_mlen);
307 + rprintf(FERROR,"Error Connecting to Database %s\n",V_OD_msg);
308 + SQLFreeHandle(SQL_HANDLE_DBC,db_handle);
310 + SQLFreeHandle(SQL_HANDLE_ENV, db_environ_handle);
311 + db_environ_handle = NULL;
314 + rprintf(FLOG,"Connected to database!\n");
316 + /* get SQL statement handle */
317 + result = SQLAllocHandle(SQL_HANDLE_STMT, db_handle, &sql_statement_handle);
318 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
319 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
320 + rprintf(FERROR,"Error in allocating SQL statement handle %s\n",V_OD_msg);
321 + SQLDisconnect(db_handle);
322 + SQLFreeHandle(SQL_HANDLE_DBC,db_handle);
324 + SQLFreeHandle(SQL_HANDLE_ENV, db_environ_handle);
325 + db_environ_handle = NULL;
329 + rprintf(FERROR,"Already connected to database\n");
336 + if (lp_database_logging(module_id)) {
337 + if (sql_statement_handle != NULL) {
338 + /* free the statement handle first */
339 + SQLFreeHandle(SQL_HANDLE_STMT,sql_statement_handle);
340 + sql_statement_handle = NULL;
342 + rprintf(FERROR,"No sql statement handle to close\n");
344 + if (db_handle != NULL) {
345 + /* disconnect, and free the database handle. */
346 + SQLDisconnect(db_handle);
347 + SQLFreeHandle(SQL_HANDLE_DBC,db_handle);
350 + rprintf(FERROR,"Database already closed");
352 + if (db_environ_handle != NULL) {
353 + /* free the environment handle */
354 + SQLFreeHandle(SQL_HANDLE_ENV, db_environ_handle);
355 + db_environ_handle = NULL;
357 + rprintf(FERROR,"No environment handle to close");
362 +static long get_unique_session_id()
365 + char strSqlStatement[1024];
367 + if (db_handle != NULL) {
368 + /* choose the appropriate select statement based upon which DBMS we're using.
369 + * different datbases use different methods to get a unique ID. Some use a counter
370 + * object (sequence), others use an auto increment datatype and have a method
371 + * to get the last ID inserted using this connection. */
372 + if (strcmp(lp_unique_id_method(module_id),"nextval-postgresql") == 0) {
373 + snprintf(strSqlStatement,sizeof(strSqlStatement),"SELECT NEXTVAL('%s');",lp_sequence_name(module_id));
374 + } else if (strcmp(lp_unique_id_method(module_id),"nextval-oracle") == 0) {
375 + snprintf(strSqlStatement,sizeof(strSqlStatement),"SELECT %s.NEXTVAL FROM dual;",lp_sequence_name(module_id));
376 + } else if (strcmp(lp_unique_id_method(module_id),"nextval-db2") == 0) {
377 + snprintf(strSqlStatement,sizeof(strSqlStatement),"VALUES NEXTVAL FOR %s;",lp_sequence_name(module_id));
378 + } else if (strcmp(lp_unique_id_method(module_id),"last_insert_id") == 0) { /* MySql */
379 + snprintf(strSqlStatement,sizeof(strSqlStatement),"SELECT LAST_INSERT_ID()");
380 + } else if (strcmp(lp_unique_id_method(module_id),"@@IDENTITY") == 0) { /* Sybase */
381 + snprintf(strSqlStatement,sizeof(strSqlStatement),"SELECT @@IDENTITY");
382 + } else if (strcmp(lp_unique_id_method(module_id),"custom") == 0){ /* Users custom statement */
383 + snprintf(strSqlStatement,sizeof(strSqlStatement),lp_custom_unique_id_select(module_id));
386 + /* bind the 1st column to unique */
387 + SQLBindCol(sql_statement_handle,1,SQL_C_LONG,&unique,150,&V_OD_err);
388 + /* execute the SQL statement */
389 + result = SQLExecDirect(sql_statement_handle,strSqlStatement,SQL_NTS);
390 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
391 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
392 + rprintf(FERROR,"Error at get_sequence: Error in Select! %s %s\n",strSqlStatement,V_OD_msg);
394 + result = SQLFetch(sql_statement_handle);
395 + if (result != SQL_NO_DATA && unique != 0) {
396 + rprintf(FINFO,"Got unique sequence! %ld\n",unique);
398 + rprintf(FERROR,"Error at get_sequence: Didn't get unique session ID\n");
400 + /* Close the cursor so the statement can be re-used */
401 + result = SQLFreeStmt(sql_statement_handle,SQL_CLOSE);
402 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
403 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
404 + rprintf(FERROR,"Error at get_sequence: Error in closing SQL statement handle %s\n",V_OD_msg);
410 + rprintf(FERROR,"Error at get_sequence: Not connected to database\n");
415 +void db_log_session()
417 + char strSqlStatement[1024];
418 + int gotSessionID = 0;
419 + if (lp_database_logging(module_id)) {
420 + /* if we're using a sequence via the nextval command to get a unique ID, we need to get it before
421 + * we do the insert. We also get the unique ID now if custom, and get_custom_id_before_insert is set. */
422 + if (strcmp(lp_unique_id_method(module_id),"nextval-postgresql") == 0
423 + || strcmp(lp_unique_id_method(module_id),"nextval-oracle") == 0
424 + || strcmp(lp_unique_id_method(module_id),"nextval-db2") == 0
425 + || (strcmp(lp_unique_id_method(module_id),"custom") == 0
426 + && lp_get_custom_id_before_insert(module_id))) {
427 + session_id = get_unique_session_id();
429 + snprintf(strSqlStatement,sizeof(strSqlStatement),"INSERT INTO %s (id, date, ip_address, username, module_name, module_path, process_id) VALUES ('%ld', '%s', '%s', '%s','%s','%s','%d');",lp_session_table_name(module_id),session_id,timestring(time(NULL)),client_addr(0),auth_user,lp_name(module_id),lp_path(module_id),getpid());
431 + /* Otherwise the ID gets created automatically, and we get the ID it used after the insert. */
432 + snprintf(strSqlStatement,sizeof(strSqlStatement),"INSERT INTO %s (date, ip_address, username, module_name, module_path, process_id) VALUES ('%s', '%s', '%s', '%s','%s','%d');",lp_session_table_name(module_id),timestring(time(NULL)),client_addr(0),auth_user,lp_name(module_id),lp_path(module_id),getpid());
435 + /* Insert the new session into the database */
436 + result = SQLExecDirect(sql_statement_handle,strSqlStatement,SQL_NTS);
437 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
438 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
439 + rprintf(FERROR,"Error at db_log_session: Error in Insert %s %s\n",strSqlStatement,V_OD_msg);
442 + /* close the cursor so the statement handle can be re-used. */
443 + result = SQLFreeStmt(sql_statement_handle,SQL_CLOSE);
444 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
445 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
446 + rprintf(FERROR,"Error in resetting SQL statement handle %s\n",V_OD_msg);
448 + /* get the session ID for databases that give the unique ID after an insert */
449 + if (gotSessionID == 0) {
450 + session_id = get_unique_session_id();
454 + rprintf(FERROR,"Error at db_log_session: Not connected to database!\n");
458 +void db_log_transfer(struct file_struct *file,struct stats *initial_stats,char *operation)
460 + extern struct stats stats;
461 + char strSqlStatement[1024];
462 + char strFilePath[255];
463 + char strFileName[255];
464 + char strFileSize[255];
465 + int64 intBytesTransferred;
466 + int64 intCheckSumBytes;
468 + if (lp_database_logging(module_id)) {
469 + if (db_handle != NULL) {
470 + snprintf(strFileName,sizeof(strFileName), "%s",f_name(file));
471 + snprintf(strFilePath, sizeof(strFilePath), "%s", file->basedir?file->basedir:"");
472 + snprintf(strFileSize,sizeof(strFileSize),"%.0f", (double)file->length);
474 + intBytesTransferred = stats.total_written - initial_stats->total_written;
476 + intBytesTransferred = stats.total_read - initial_stats->total_read;
480 + intCheckSumBytes = stats.total_written - initial_stats->total_written;
482 + intCheckSumBytes = stats.total_read - initial_stats->total_read;
485 + snprintf(strSqlStatement,sizeof(strSqlStatement),"INSERT INTO %s (session_id,date,file_path, file_name, file_size, bytes_transferred, checksum_bytes_transferred, operation) VALUES ('%ld','%s','%s','%s','%s','%Ld','%Ld','%s');",lp_transfer_table_name(module_id),session_id,timestring(time(NULL)),sanitizeSql(strFilePath),sanitizeSql(strFileName),strFileSize,intBytesTransferred,intCheckSumBytes,operation);
486 + result = SQLExecDirect(sql_statement_handle,strSqlStatement,SQL_NTS);
487 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
488 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
489 + rprintf(FERROR,"Error at db_log_transfer: Error in Insert %s %s\n",strSqlStatement,V_OD_msg);
490 + if (result == SQL_INVALID_HANDLE)
491 + rprintf(FERROR,"INVALID HANDLE\n");
494 + rprintf(FERROR,"Error at db_log_transfer: Not connected to database!\n");
500 +void db_log_exit(int code, const char *file, int line)
502 + char strSqlStatement[2048];
503 + const char *error_text;
504 + extern struct stats stats;
505 + if (db_handle != NULL) {
506 + if (lp_database_logging(module_id)) {
508 + error_text = rerr_name(code);
510 + error_text = "unexplained error";
515 + snprintf(strSqlStatement,sizeof(strSqlStatement),"INSERT INTO %s (session_id, date, total_bytes_written,total_bytes_read,total_size,error_text,error_code,error_file,error_line) VALUES ('%ld','%s','%Ld','%Ld','%Ld','%s','%d','%s','%d');",lp_exit_table_name(module_id),session_id,timestring(time(NULL)),stats.total_written,stats.total_read,stats.total_size,error_text,code,file,line);
517 + result = SQLExecDirect(sql_statement_handle,strSqlStatement,SQL_NTS);
519 + if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
520 + SQLGetDiagRec(SQL_HANDLE_DBC, db_handle,1, sql_status,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
521 + rprintf(FERROR,"Error at db_log_exit: Error in Insert %s %s\n",strSqlStatement,V_OD_msg);
525 + rprintf(FERROR,"Error at db_log_exit: Not connected to database!\n");
528 --- dblog-tables-mysql.sql 2004-02-13 17:08:33.000000000 -0800
529 +++ dblog-tables-mysql.sql 2004-04-07 23:00:13.000000000 -0700
531 +drop table transfer;
535 +CREATE TABLE session (
536 + id int auto_increment NOT NULL,
537 + date timestamp NOT NULL,
538 + ip_address varchar(15) NOT NULL,
539 + username varchar(20) NOT NULL,
540 + module_name varchar(20) NOT NULL,
541 + module_path varchar(255) NOT NULL,
542 + process_id int NOT NULL,
546 +CREATE TABLE transfer (
547 + id int auto_increment NOT NULL,
548 + session_id int NOT NULL,
549 + date timestamp NOT NULL,
550 + file_path varchar(255) NOT NULL,
551 + file_name varchar(255) NOT NULL,
552 + file_size bigint NOT NULL,
553 + bytes_transferred bigint NOT NULL,
554 + checksum_bytes_transferred bigint NOT NULL,
555 + operation varchar(20),
557 + foreign key (session_id) references session (id)
561 + id int auto_increment NOT NULL,
562 + session_id int NOT NULL,
563 + date timestamp NOT NULL,
564 + total_bytes_written bigint NOT NULL,
565 + total_bytes_read bigint NOT NULL,
566 + total_size bigint NOT NULL,
567 + error_text varchar(128) NOT NULL,
568 + error_code int NOT NULL,
569 + error_file varchar(64) NOT NULL,
570 + error_line int NOT NULL,
572 + foreign key (session_id) references session (id)
574 --- dblog-tables-postgresql.sql 2004-02-13 17:08:33.000000000 -0800
575 +++ dblog-tables-postgresql.sql 2004-04-07 22:59:55.000000000 -0700
577 +drop table transfer;
580 +drop sequence session_id_seq;
581 +create sequence session_id_seq;
583 +CREATE TABLE "session" (
585 + "date" timestamp NOT NULL default now(),
586 + "ip_address" varchar(15) NOT NULL,
587 + "username" varchar(20) NOT NULL,
588 + "module_name" varchar(20) NOT NULL,
589 + "module_path" varchar(255) NOT NULL,
590 + "process_id" int NOT NULL,
594 +CREATE TABLE "transfer" (
595 + "id" serial NOT NULL,
596 + "session_id" int NOT NULL,
597 + "date" timestamp NOT NULL default now(),
598 + "file_path" varchar(512) NOT NULL,
599 + "file_name" varchar(512) NOT NULL,
600 + "file_size" bigint NOT NULL,
601 + "bytes_transferred" bigint NOT NULL,
602 + "checksum_bytes_transferred" bigint NOT NULL,
603 + "operation" varchar(20),
605 + foreign key (session_id) references session (id)
608 +CREATE TABLE "exit" (
609 + "id" serial NOT NULL,
610 + "session_id" int NOT NULL,
611 + "date" timestamp NOT NULL default now(),
612 + "total_bytes_written" bigint NOT NULL,
613 + "total_bytes_read" bigint NOT NULL,
614 + "total_size" bigint NOT NULL,
615 + "error_text" varchar(128) NOT NULL,
616 + "error_code" int NOT NULL,
617 + "error_file" varchar(64) NOT NULL,
618 + "error_line" int NOT NULL,
620 + foreign key (session_id) references session (id)
622 --- loadparm.c 4 Feb 2004 07:31:29 -0000 1.50
623 +++ loadparm.c 8 Apr 2004 06:31:18 -0000
627 BOOL transfer_logging;
628 + BOOL database_logging;
629 + char *database_datasource;
630 + char *database_username;
631 + char *database_password;
632 + char *transfer_table_name;
633 + char *exit_table_name;
634 + char *session_table_name;
635 + char *sequence_name;
636 + char *unique_id_method;
637 + char *custom_unique_id_select;
638 + BOOL get_custom_id_before_insert;
644 True, /* use chroot */
645 False, /* transfer logging */
646 + False, /* Database Logging */
647 + NULL, /* Database datasource */
648 + NULL, /* Database username */
649 + NULL, /* Database password */
650 + NULL, /* Transfer table name */
651 + NULL, /* Exit table name */
652 + NULL, /* Session table name */
653 + NULL, /* sequence name */
654 + NULL, /* unique method */
655 + NULL, /* custom unique id select*/
656 + True, /* get custom id before insert */
657 False, /* ignore errors */
661 {"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
662 {"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
663 {"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
664 + {"database logging", P_BOOL, P_LOCAL, &sDefault.database_logging,NULL,0},
665 + {"database datasource",P_STRING,P_LOCAL, &sDefault.database_datasource,NULL,0},
666 + {"database username",P_STRING, P_LOCAL, &sDefault.database_username,NULL,0},
667 + {"database password",P_STRING, P_LOCAL, &sDefault.database_password,NULL,0},
668 + {"transfer table name",P_STRING,P_LOCAL, &sDefault.transfer_table_name,NULL,0},
669 + {"exit table name", P_STRING, P_LOCAL, &sDefault.exit_table_name,NULL,0},
670 + {"session table name",P_STRING, P_LOCAL, &sDefault.session_table_name,NULL,0},
671 + {"sequence name", P_STRING, P_LOCAL, &sDefault.sequence_name,NULL,0},
672 + {"unique id method", P_STRING, P_LOCAL, &sDefault.unique_id_method,NULL,0},
673 + {"custom unique id select",P_STRING,P_LOCAL,&sDefault.custom_unique_id_select,NULL,0},
674 + {"get custom id before insert",P_BOOL,P_LOCAL,&sDefault.get_custom_id_before_insert,NULL,0},
675 {"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors,NULL,0},
676 {"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
677 {"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
679 FN_LOCAL_BOOL(lp_list, list)
680 FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
681 FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
682 +FN_LOCAL_BOOL(lp_database_logging, database_logging)
683 +FN_LOCAL_STRING(lp_database_datasource, database_datasource)
684 +FN_LOCAL_STRING(lp_database_username, database_username)
685 +FN_LOCAL_STRING(lp_database_password, database_password)
686 +FN_LOCAL_STRING(lp_transfer_table_name, transfer_table_name)
687 +FN_LOCAL_STRING(lp_exit_table_name, exit_table_name)
688 +FN_LOCAL_STRING(lp_session_table_name,session_table_name)
689 +FN_LOCAL_STRING(lp_sequence_name,sequence_name)
690 +FN_LOCAL_STRING(lp_unique_id_method,unique_id_method)
691 +FN_LOCAL_STRING(lp_custom_unique_id_select,custom_unique_id_select)
692 +FN_LOCAL_BOOL(lp_get_custom_id_before_insert,get_custom_id_before_insert)
693 FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
694 FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
695 FN_LOCAL_STRING(lp_uid, uid)
696 --- log.c 20 Jan 2004 05:15:14 -0000 1.71
697 +++ log.c 8 Apr 2004 05:56:32 -0000
700 * Map from rsync error code to name, or return NULL.
702 -static char const *rerr_name(int code)
703 +char const *rerr_name(int code)
706 for (i = 0; rerr_names[i].name; i++) {
707 --- main.c 10 Feb 2004 03:54:47 -0000 1.192
708 +++ main.c 8 Apr 2004 05:56:32 -0000
712 log_exit(0, __FILE__, __LINE__);
714 + db_log_exit(0,__FILE__,__LINE__);
716 if (f == -1 || !am_sender) return;
719 --- proto.h 14 Apr 2004 23:33:30 -0000 1.188
720 +++ proto.h 15 Apr 2004 18:51:15 -0000
722 int daemon_main(void);
723 void setup_protocol(int f_out,int f_in);
724 int claim_connection(char *fname,int max_connections);
725 +char *sanitizeSql(const char *input);
726 +void db_log_open(void);
727 +void db_log_close();
728 +void db_log_session();
729 +void db_log_transfer(struct file_struct *file,struct stats *initial_stats,char *operation);
730 +void db_log_exit(int code, const char *file, int line);
731 void free_exclude_list(struct exclude_list_struct *listp);
732 int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir,
736 BOOL lp_use_chroot(int );
737 BOOL lp_transfer_logging(int );
738 +BOOL lp_database_logging(int );
739 +char *lp_database_datasource(int );
740 +char *lp_database_username(int );
741 +char *lp_database_password(int );
742 +char *lp_transfer_table_name(int );
743 +char *lp_exit_table_name(int );
744 +char *lp_session_table_name(int );
745 +char *lp_sequence_name(int );
746 +char *lp_unique_id_method(int );
747 +char *lp_custom_unique_id_select(int );
748 +BOOL lp_get_custom_id_before_insert(int );
749 BOOL lp_ignore_errors(int );
750 BOOL lp_ignore_nonreadable(int );
753 BOOL lp_load(char *pszFname, int globals_only);
754 int lp_numservices(void);
755 int lp_number(char *name);
756 +char const *rerr_name(int code);
759 void log_close(void);
760 --- receiver.c 23 Mar 2004 16:50:40 -0000 1.75
761 +++ receiver.c 8 Apr 2004 05:56:32 -0000
763 recv_ok = receive_data(f_in,mapbuf,fd2,fname,file->length);
765 log_recv(file, &initial_stats);
768 + db_log_transfer(file, &initial_stats,"receive");
770 if (mapbuf) unmap_file(mapbuf);
773 --- sender.c 17 Feb 2004 21:57:44 -0000 1.38
774 +++ sender.c 8 Apr 2004 05:56:32 -0000
777 match_sums(f_out, s, buf, st.st_size);
778 log_send(file, &initial_stats);
780 + db_log_transfer(file, &initial_stats,"send");