From 7bf96955732f27e1a74b0a4c3e0f4f666c123359 Mon Sep 17 00:00:00 2001 From: Stefan Ritt Date: Mon, 19 Jan 2004 16:22:28 +0000 Subject: [PATCH] Continued working on synchronization SVN revision: 696 --- src/elogd.c | 292 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 215 insertions(+), 77 deletions(-) diff --git a/src/elogd.c b/src/elogd.c index 279f53c3..00aa1135 100755 --- a/src/elogd.c +++ b/src/elogd.c @@ -6,6 +6,9 @@ Contents: Web server program for Electronic Logbook ELOG $Log$ + Revision 1.200 2004/01/19 16:22:28 midas + Continued working on synchronization + Revision 1.199 2004/01/19 09:13:28 midas Removed '{n}' in quick filter and find page list @@ -3179,7 +3182,7 @@ INT el_retrieve_attachment(LOGBOOK * lbs, int message_id, int n, /*------------------------------------------------------------------*/ -int el_submit(LOGBOOK * lbs, int message_id, +int el_submit(LOGBOOK * lbs, int message_id, BOOL bedit, char *date, char attr_name[MAX_N_ATTR][NAME_LENGTH], char attr_value[MAX_N_ATTR][NAME_LENGTH], @@ -3195,8 +3198,8 @@ int el_submit(LOGBOOK * lbs, int message_id, Input: LOGBOOK lbs Logbook structure - int message_id Message id for existing message, 0 for - new message + int message_id Message id + BOOL bedit TRUE for existing message, FALSE for new message char *date Message date char attr_name[][] Name of attributes char attr_value[][] Value of attributes @@ -3223,14 +3226,11 @@ int el_submit(LOGBOOK * lbs, int message_id, char file_name[256], dir[256], str[NAME_LENGTH]; time_t now, ltime; char message[TEXT_SIZE + 100], *p, *buffer; - BOOL bedit; char attachment_all[64 * MAX_ATTACHMENTS]; /* generate new file name YYMMDD.log in data directory */ strcpy(dir, lbs->data_dir); - bedit = (message_id > 0); - if (bedit) { /* edit existing message */ for (index = 0; index < *lbs->n_el_index; index++) @@ -3255,7 +3255,7 @@ int el_submit(LOGBOOK * lbs, int message_id, /* file might have been edited, rebuild index */ el_build_index(lbs, TRUE); - return el_submit(lbs, message_id, date, attr_name, attr_value, + return el_submit(lbs, message_id, bedit, date, attr_name, attr_value, n_attr, text, in_reply_to, reply_to, encoding, afilename, TRUE, locked_by); } @@ -3337,10 +3337,12 @@ int el_submit(LOGBOOK * lbs, int message_id, lseek(fh, 0, SEEK_END); /* new message id is old plus one */ - message_id = 1; - for (i = 0; i < *lbs->n_el_index; i++) - if (lbs->el_index[i].message_id >= message_id) - message_id = lbs->el_index[i].message_id + 1; + if (message_id == 0) { + message_id = 1; + for (i = 0; i < *lbs->n_el_index; i++) + if (lbs->el_index[i].message_id >= message_id) + message_id = lbs->el_index[i].message_id + 1; + } /* enter message in index */ index = *lbs->n_el_index; @@ -3445,7 +3447,7 @@ int el_submit(LOGBOOK * lbs, int message_id, sprintf(reply_to + strlen(reply_to), "%d", message_id); /* write modified message */ - el_submit(lbs, reply_id, date, attr_list, attr, n_attr, message, in_reply_to, + el_submit(lbs, reply_id, TRUE, date, attr_list, attr, n_attr, message, in_reply_to, reply_to, enc, att, TRUE, lock); } @@ -3493,8 +3495,8 @@ void remove_reference(LOGBOOK * lbs, int message_id, int remove_id, BOOL reply_t } /* write modified message */ - el_submit(lbs, message_id, date, attr_list, attr, lbs->n_attr, message, in_reply_to, - reply_to, enc, att, TRUE, lock); + el_submit(lbs, message_id, TRUE, date, attr_list, attr, lbs->n_attr, message, + in_reply_to, reply_to, enc, att, TRUE, lock); } /*------------------------------------------------------------------*/ @@ -3740,7 +3742,7 @@ This routine corrects that. */ strcat(reply_to, ", "); } - el_submit(lbs, atoi(list[i]), date, attr_list, attrib, lbs->n_attr, + el_submit(lbs, atoi(list[i]), TRUE, date, attr_list, attrib, lbs->n_attr, text, in_reply_to, reply_to, encoding, att_file, TRUE, locked_by); } @@ -3767,7 +3769,7 @@ This routine corrects that. */ strcat(in_reply_to, ", "); } - el_submit(lbs, atoi(list[i]), date, attr_list, attrib, lbs->n_attr, + el_submit(lbs, atoi(list[i]), TRUE, date, attr_list, attrib, lbs->n_attr, text, in_reply_to, reply_to, encoding, att_file, TRUE, locked_by); } @@ -3791,7 +3793,7 @@ int el_move_message_thread(LOGBOOK * lbs, int message_id) /* submit as new message */ date[0] = 0; - new_id = el_submit(lbs, 0, date, attr_list, attrib, lbs->n_attr, text, + new_id = el_submit(lbs, 0, FALSE, date, attr_list, attrib, lbs->n_attr, text, in_reply_to, reply_to, encoding, att_file, FALSE, locked_by); /* correct links */ @@ -3828,8 +3830,8 @@ int el_lock_message(LOGBOOK * lbs, int message_id, char *user) text, &size, in_reply_to, reply_to, att_file, encoding, locked_by); /* submit message, unlocked if user==NULL */ - el_submit(lbs, message_id, date, attr_list, attrib, lbs->n_attr, text, in_reply_to, - reply_to, encoding, att_file, FALSE, user); + el_submit(lbs, message_id, TRUE, date, attr_list, attrib, lbs->n_attr, text, + in_reply_to, reply_to, encoding, att_file, FALSE, user); return EL_SUCCESS; } @@ -6639,8 +6641,7 @@ void show_find_form(LOGBOOK * lbs) option); if (comment[0]) - rsprintf("\"%s\"\n", - option, comment); + rsprintf("\"%s\"\n", option, comment); else rsprintf("\n", option); } @@ -8084,6 +8085,10 @@ int submit_message(LOGBOOK * lbs, char *url, int message_id, char *error_str) strcpy(content, boundary); strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n"); + sprintf(content + strlen(content), + "%s\r\nContent-Disposition: form-data; name=\"mirror_id\"\r\n\r\n%d\r\n", + boundary, message_id); + if (isparam("unm")) sprintf(content + strlen(content), "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n", @@ -8110,7 +8115,7 @@ int submit_message(LOGBOOK * lbs, char *url, int message_id, char *error_str) attr_list[i], attrib[i]); sprintf(content + strlen(content), - "%s\r\nContent-Disposition: form-data; name=\"remote_date\"\r\n\r\n%s\r\n", + "%s\r\nContent-Disposition: form-data; name=\"entry_date\"\r\n\r\n%s\r\n", boundary, date); sprintf(content + strlen(content), @@ -8250,6 +8255,13 @@ int submit_message(LOGBOOK * lbs, char *url, int message_id, char *error_str) /*------------------------------------------------------------------*/ +int receive_message(LOGBOOK * lbs, char *url, int message_id, char *error_str) +{ + return 1; +} + +/*------------------------------------------------------------------*/ + int save_md5(char *server, MD5_INDEX * md5_index, int n) { char str[256], file_name[256]; @@ -8288,11 +8300,80 @@ int save_md5(char *server, MD5_INDEX * md5_index, int n) /*------------------------------------------------------------------*/ +int load_md5(char *server, MD5_INDEX ** md5_index) +{ + char str[256], file_name[256], *p; + int i, j; + FILE *f; + + strlcpy(file_name, resource_dir, sizeof(file_name)); + strcpy(str, server); + if (strstr(str, "http://")) + strcpy(str, server + 7); + + for (i = 0; i < (int) strlen(str); i++) + if (strchr(":/\\", str[i])) + str[i] = '_'; + + while (str[strlen(str) - 1] == '_') + str[strlen(str) - 1] = 0; + + strlcat(file_name, str, sizeof(file_name)); + strlcat(file_name, ".md5", sizeof(file_name)); + + f = fopen(file_name, "rt"); + if (f == NULL) + return 0; + + for (i = 0; !feof(f); i++) { + str[0] = 0; + fgets(str, sizeof(str), f); + if (!str[0]) + break; + + if (i == 0) + *md5_index = calloc(sizeof(MD5_INDEX), 1); + else + *md5_index = realloc(md5_index, sizeof(MD5_INDEX) * (i + 1)); + + p = str + 2; + + (*md5_index)[i].message_id = atoi(p); + while (*p && *p != ' ') + p++; + while (*p && *p == ' ') + p++; + + for (j = 0; j < 16; j++) + sscanf(p + j * 2, "%02X", (*md5_index)[i].md5_digest[j]); + } + + fclose(f); + return i; +} + +/*------------------------------------------------------------------*/ + +BOOL equal_md5(unsigned char m1[16], unsigned char m2[16]) +{ + int i; + for (i = 0; i < 16; i++) + if (m1[i] != m2[i]) + break; + + return i == 16; +} + +/*------------------------------------------------------------------*/ + void synchronize(LOGBOOK * lbs, char *path) { - int index, i, j, k, n, nserver, priority_remote = 0; + int index, i, i_remote, i_cache, n_remote, n_cache, nserver, + remote_id, exist_remote, exist_cache, message_id; + + int priority_remote = 0; char str[2000]; - MD5_INDEX *md5_index; + MD5_INDEX *md5_remote, *md5_cache; char list[MAX_N_LIST][NAME_LENGTH], error_str[256]; if (!getcfg(lbs->name, "Mirror server", str)) { @@ -8320,77 +8401,112 @@ void synchronize(LOGBOOK * lbs, char *path) rsprintf("\n", loc("Synchronizing with"), list[index]); - rsprintf("
%s %s

\n"); + rsprintf("

\n");
 
       /* send partial return buffer */
       flush_return_buffer();
 
       sprintf(str, "%s?cmd=GetMD5", list[index]);
-      n = retrieve_remote_md5(str, &md5_index);
-      if (n < 0) {
-         free(md5_index);
+      n_remote = retrieve_remote_md5(str, &md5_remote);
+      if (n_remote < 0) {
+         rsprintf("Error receiving remote message list from \"%s\"\n", list[index]);
+         free(md5_remote);
          continue;
       }
 
+      /* load local copy of remote MD5s from file */
+      n_cache = load_md5(list[index], &md5_cache);
+
       /* loop through logbook entries */
       for (i = 0; i < *lbs->n_el_index; i++) {
-         rsprintf("ID: %6d ", lbs->el_index[i].message_id);
 
-         for (j = 0; j < n; j++)
-            if (md5_index[j].message_id == lbs->el_index[i].message_id)
+         message_id = lbs->el_index[i].message_id;
+         rsprintf("ID%d: ", message_id);
+
+         /* look for message id in MD5s */
+         for (i_remote = 0; i_remote < n_remote; i_remote++)
+            if (md5_remote[i_remote].message_id == message_id)
                break;
+         exist_remote = i_remote < n_remote;
 
-         if (j < n) {
-            /* message found, compare MD5 */
+         for (i_cache = 0; i_cache < n_cache; i_cache++)
+            if (md5_cache[i_cache].message_id == message_id)
+               break;
+         exist_cache = i_cache < n_cache;
 
-            for (k = 0; k < 16; k++)
-               if (md5_index[j].md5_digest[k] != lbs->el_index[j].md5_digest[k])
-                  break;
+         /* if message exists in both lists, compare MD5s */
+         if (exist_remote && exist_cache) {
 
-            if (k < 16) {
-               if (priority_remote) {
-                  /* retrieve remote message */
-                  rsprintf("Retrieve remote message
\n"); - } else { - /* submit local message */ - submit_message(lbs, list[index], lbs->el_index[i].message_id, - error_str); + /* if message has been changed on this server, but not remotely, send it */ + if (!equal_md5(md5_cache[i_cache].md5_digest, lbs->el_index[index].md5_digest) + && equal_md5(md5_cache[i_cache].md5_digest, + md5_remote[i_remote].md5_digest)) { - if (error_str[0]) - rsprintf("Error sending local message: %s
\n", error_str); - else - rsprintf("Local message submitted
\n"); - } - } else { - rsprintf("%s
\n", loc("Message identical")); - } - } else { - /* message not found remotely */ - if (priority_remote) { - /* delete local message */ - rsprintf("Delete local message
\n"); - } else { - /* submit message */ - submit_message(lbs, list[index], lbs->el_index[i].message_id, error_str); + /* submit local message */ + submit_message(lbs, list[index], message_id, error_str); if (error_str[0]) - rsprintf("Error sending local message: %s
\n", error_str); + rsprintf("Error sending local message: %s\n", error_str); else - rsprintf("Local message submitted
\n"); - } + rsprintf("Local message submitted\n"); + + } else + /* if message has been changed remotely, but not on this server, receive it */ + if (!equal_md5 + (md5_cache[i_cache].md5_digest, md5_remote[i_remote].md5_digest) + && equal_md5(md5_cache[i_cache].md5_digest, + lbs->el_index[index].md5_digest)) { + + receive_message(lbs, list[index], message_id, error_str); + } else + /* if message has been changed remotely and on this server, show conflict */ + if (!equal_md5 + (md5_cache[i_cache].md5_digest, md5_remote[i_remote].md5_digest) + && !equal_md5(md5_cache[i_cache].md5_digest, + lbs->el_index[index].md5_digest)) { + + rsprintf("%s\n", + loc + ("Message has been changed locally and remotely, please delete one to resolve conflict")); + + } else + + rsprintf("%s\n", loc("Message identical")); } + + /* if message exists only in cache, but not remotely, + it must have been deleted remotely, so remove it locally */ + if (exist_cache && !exist_remote) { + el_delete_message(lbs, message_id, TRUE, NULL, TRUE, TRUE); + rsprintf("%s\n", loc("Message has been deleted locally")); + } + + /* if message does not exist in cache and remotely, + it must be new, so send it */ + if (!exist_cache && !exist_remote) { + remote_id = + submit_message(lbs, list[index], lbs->el_index[i].message_id, error_str); + + if (error_str[0]) + rsprintf("%s: %s\n", loc("Error sending local message"), error_str); + else + rsprintf("%s\n", loc("Local message submitted")); + } + + flush_return_buffer(); } - free(md5_index); + free(md5_remote); + free(md5_cache); /* save remote MD5s in file */ sprintf(str, "%s?cmd=GetMD5", list[index]); - n = retrieve_remote_md5(str, &md5_index); - save_md5(list[index], md5_index, n); - free(md5_index); + n_remote = retrieve_remote_md5(str, &md5_remote); + save_md5(list[index], md5_remote, n_remote); + free(md5_remote); } - rsprintf("\n"); + rsprintf("
\n"); flush_return_buffer(); keep_alive = 0; } @@ -9053,6 +9169,9 @@ BOOL is_command_allowed(LOGBOOK * lbs, char *command) strcat(menu_str, "Admin, "); strcat(menu_str, "Change elogd.cfg, "); + if (getcfg(lbs->name, "Mirror server", str)) + strcat(menu_str, "Synchronize, "); + if (!getcfg("global", "Admin user", str) || strstr(str, getparam("unm")) != 0) { @@ -9072,6 +9191,8 @@ BOOL is_command_allowed(LOGBOOK * lbs, char *command) } strcat(menu_str, "Config, Logout, "); } else { + if (getcfg(lbs->name, "Mirror server", str)) + strcat(menu_str, "Synchronize, "); strcat(menu_str, "Config, "); strcat(menu_str, "Change [global]"); strcat(menu_str, ", "); @@ -9348,11 +9469,9 @@ void show_page_filters(LOGBOOK * lbs, int n_msg, int page_n, int n_page, BOOL to if (isparam(attr_list[i]) && equal_ustring(option, getparam(attr_list[i]))) - rsprintf("