Update of /cvsroot/multisync/multisync/plugins/sunbird_plugin/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30137/src Modified Files: Tag: branch_08X Makefile Makefile.am Makefile.in sunbird_plugin.c tools.c Added Files: Tag: branch_08X webdav.c webdav.h Log Message: added webdav support Index: sunbird_plugin.c =================================================================== RCS file: /cvsroot/multisync/multisync/plugins/sunbird_plugin/src/Attic/sunbird_plugin.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -d -r1.1.2.2 -r1.1.2.3 --- sunbird_plugin.c 6 Mar 2005 01:30:49 -0000 1.1.2.2 +++ sunbird_plugin.c 7 Mar 2005 01:51:33 -0000 1.1.2.3 @@ -24,19 +24,77 @@ */ #include "sunbird_plugin.h" +#include "webdav.h" + +int do_webdav(ical_connection* conn, int upload) +{ + const char* username = g_getenv("MULTISYNC_SUNBIRD_WEBDAV_USERNAME"); + const char* password = g_getenv("MULTISYNC_SUNBIRD_WEBDAV_PASSWORD"); + int result = TRUE, tmpresult; + GList *f, *l; + GList* links = get_calendar_files_list(conn, TRUE); + GList* files = get_calendar_files_list(conn, FALSE); + + printf("--- do_webdav BEGIN ---\n"); + + if (!username || !password) + { + printf("WARNING: MULTISYNC_SUNBIRD_WEBDAV_USERNAME or MULTISYNC_SUNBIRD_WEBDAV_PASSWORD\n"); + printf(" not set, disabling WebDAV transfer...\n"); + return FALSE; + } + + l = g_list_first(links); + f = g_list_first(files); + while (l) + { + if (strncmp((char*)l->data, "http://", 7) == 0) + { + if (upload) + { + printf("Uploading %s -> %s\n", (char*)f->data, (char*)l->data); + tmpresult = webdav_upload((char*)f->data, (char*)l->data, (char*)username, (char*)password); + } else + { + printf("Downloading %s -> %s\n", (char*)l->data, (char*)f->data); + tmpresult = webdav_download((char*)f->data, (char*)l->data, (char*)username, (char*)password); + } + + if (tmpresult != WEBDAV_SUCCESS) + { + printf("ERROR: webdav function returned status %i\n", tmpresult); + result = FALSE; + } + } + + l = l->next; + f = f->next; + } + + free_string_list(files); + free_string_list(links); + + printf("--- do_webdav END ---\n"); + + return result; +} ical_connection* sync_connect(sync_pair* handle, connection_type type, sync_object_type object_types) { ical_connection *conn; - + + printf("*** sync_connect ***\n"); conn = g_malloc0(sizeof(ical_connection)); g_assert(conn); conn->sync_pair = handle; conn->commondata.object_types = object_types; conn->pending_changes = NULL; + /* FIXME: Error handling for webdav transfer */ + do_webdav(conn, 0); + sync_set_requestdone(conn->sync_pair); return conn; } @@ -44,6 +102,8 @@ void sync_disconnect(ical_connection *conn) { sync_pair *sync_pair = conn->sync_pair; + + printf("*** sync_disconnect ***\n"); if (conn->pending_changes) { @@ -56,7 +116,7 @@ sync_set_requestdone(sync_pair); } -GList* get_calendar_files_list() +GList* get_calendar_files_list(ical_connection* conn, int preserve_hyperlinks) { /* FIXME: We need an option dialog for that */ /* FIXME: We also should not use strtok (not multithread-safe) */ @@ -67,8 +127,31 @@ { char* pch; - for (pch = (char*)strtok(calendars_env->str, ":"); pch; pch = (char*)strtok(NULL, ":")) - files = g_list_append(files, (char*)strdup(pch)); + for (pch = (char*)strtok(calendars_env->str, ";"); pch; pch = (char*)strtok(NULL, ";")) + { + char* s; + + if (preserve_hyperlinks || strncmp(pch, "http://", 7) != 0) + { + /* Return string as-is */ + s = (char*)strdup(pch); + } else + { + /* Get base name, and preceed with data directory */ + GString* gstr; + char* p = pch + strlen(pch); + + while (p > pch && *p != '/') + p--; + + gstr = g_string_new(sync_get_datapath(conn->sync_pair)); + g_string_append(gstr, p); + s = (char*)strdup(gstr->str); + g_string_free(gstr, TRUE); + } + + files = g_list_append(files, s); + } g_string_free(calendars_env, TRUE); calendars_env = NULL; } @@ -85,12 +168,14 @@ void write_changes_to_calendars(GList* entries, ical_connection* conn) { char keyfile[256]; - GList* files = get_calendar_files_list(), *calendars = NULL, *cur, *cur2, *curfile, *curcal, *cached_entries = NULL; + GList* files = get_calendar_files_list(conn, FALSE), *calendars = NULL, *cur, *cur2, *curfile, *curcal, *cached_entries = NULL; GString *default_calendar = g_string_new(g_getenv("MULTISYNC_SUNBIRD_DEFAULT_CALENDAR")); + printf("--- write_changes_to_calendars ---\n"); + if (!files) return; - if (!default_calendar) + if (!(default_calendar && strlen(default_calendar->str) > 0)) { char *basename_ptr = (char*)strdup((char*)g_list_first(files)->data); char *basename = basename_ptr + strlen(basename_ptr) - 1; @@ -99,7 +184,7 @@ default_calendar = g_string_new(basename); free(basename_ptr); - printf("WARNING: MULTISYNC_SUNBIRD_DEFAULT_CALENDAR not set, using first calendar: %s", default_calendar->str); + printf("WARNING: MULTISYNC_SUNBIRD_DEFAULT_CALENDAR not set, using first calendar: %s\n", default_calendar->str); } strcpy(keyfile, sync_get_datapath(conn->sync_pair)); @@ -252,6 +337,8 @@ char keyfile[256]; GList *entries = NULL, *cached_entries = NULL, *files = NULL, *cur, *cur2; + printf("--- get_calendar_changes BEGIN ---\n"); + /* Free previous pending changes, if any */ if (conn->pending_changes) { @@ -260,7 +347,7 @@ conn->pending_changes = NULL; } - files = get_calendar_files_list(); + files = get_calendar_files_list(conn, FALSE); if (!files) return FALSE; @@ -395,6 +482,8 @@ free_events_list(entries); printf("Done!\n"); + printf("--- get_calendar_changes END (SUCCESS) ---\n"); + return TRUE; err: @@ -403,6 +492,8 @@ free_events_list(cached_entries); free_events_list(entries); printf("Done!\n"); + + printf("--- get_calendar_changes END (WITH ERROR) ---\n"); return FALSE; } @@ -451,6 +542,8 @@ syncobj_modify_result *result; GList *results = NULL; char* last_modified; + + printf("--- syncobj_modify_list BEGIN ---\n"); for (node = g_list_first(changes); node; node = node->next) { @@ -461,16 +554,25 @@ { calendar_entry* entry = (calendar_entry*)g_malloc0(sizeof(calendar_entry)); + entry->remote_change_type = obj->change_type; + if (obj->comp) entry->data = g_string_new(obj->comp); else - entry->data = NULL; // no data provided + { + /* No data provided, so we assume that the entry is deleted */ + /* This is needed because e.g. IRMC plugin always uses change_type == SYNC_OBJ_MODIFIED */ + entry->remote_change_type = SYNC_OBJ_HARDDELETED; + entry->data = NULL; + } if (obj->uid && strlen(obj->uid) > 0) + { entry->id = g_string_new(obj->uid); - else + } else { - char *s, buf[256]; + /* We don't have an ID yet, so always create a new entry */ + entry->remote_change_type = SYNC_OBJ_ADDED; /* Create ID */ entry->id = create_new_uid(); @@ -480,18 +582,35 @@ else printf("ERROR: Out of memory!\n"); - printf("Created new UID=%s for entry\n", entry->id->str); + printf("Created new id '%s' for entry\n", entry->id->str); + } + + /* Always add ID as "UID" to vcard, if not there already */ + if (entry->data) + { + char* uid = sync_get_key_data(entry->data->str, "UID"); + if (uid) + { + if (strcmp(uid, entry->id->str) != 0) + { + /* If this happens, something has gone totally wrong */ + printf("ERROR: uid='%s' not the same as id='%s'\n", uid, entry->id->str); + } + g_free(uid); + } else + { + /* Add UID to VCARD */ + char *s, buf[256]; - /* Add UID to VCARD */ - sprintf(buf, "BEGIN:VEVENT\r\nUID:%s", entry->id->str); - s = strstr(entry->data->str, "BEGIN:VEVENT"); - g_string_erase(entry->data, 0, s - entry->data->str + 12); - g_string_insert(entry->data, 0, buf); + sprintf(buf, "BEGIN:VEVENT\r\nUID:%s", entry->id->str); + s = strstr(entry->data->str, "BEGIN:VEVENT"); + g_string_erase(entry->data, 0, s - entry->data->str + 12); + g_string_insert(entry->data, 0, buf); + } } entry->last_modified = NULL; // will eventually be set later entry->sourcefile = NULL; // unknown at this stage - entry->remote_change_type = obj->change_type; if (obj->change_type == SYNC_OBJ_HARDDELETED) entry->deleted = 1; @@ -524,8 +643,8 @@ printf("entry->id = %s\n", entry->id->str); else printf("entry has no id\n"); - if (entry->data->str) - printf("entry->data = %s\n", entry->data->str); + if (entry->data) + printf("entry->data:\n%s\n", entry->data->str); else printf("entry has no data\n"); } else @@ -540,7 +659,7 @@ results = g_list_append(results, result); } - printf("syncobj_modify_list END\n"); + printf("--- syncobj_modify_list END\n ---"); sync_set_requestdata(results, conn->sync_pair); } @@ -589,7 +708,7 @@ GList* cur2; calendar_entry *e = (calendar_entry*)cur->data; - if (e->deleted) + if (e->deleted || e->remote_change_type == SYNC_OBJ_HARDDELETED) { /* Delete entry from cached entries list */ for (cur2 = g_list_first(cached_entries); cur2; cur2 = cur2->next) @@ -644,6 +763,9 @@ } free_events_list(cached_entries); + + /* FIXME: Error handling for webdav transfer */ + do_webdav(conn, 1); } else { printf("Sync done, no changes\n"); @@ -654,7 +776,7 @@ gboolean always_connected() { - return TRUE; + return FALSE; } char* short_name() Index: Makefile.am =================================================================== RCS file: /cvsroot/multisync/multisync/plugins/sunbird_plugin/src/Attic/Makefile.am,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- Makefile.am 4 Feb 2005 09:50:55 -0000 1.1.2.1 +++ Makefile.am 7 Mar 2005 01:51:33 -0000 1.1.2.2 @@ -11,7 +11,10 @@ libsunbird_plugin_la_SOURCES = \ tools.c tools.h \ - sunbird_plugin.c sunbird_plugin.h + sunbird_plugin.c sunbird_plugin.h \ + webdav.c webdav.h -#libbackup_plugin_la_LIBADD = @PACKAGE_LIBS@ +NEON_LIBS = `neon-config --libs` + +libsunbird_plugin_la_LIBADD = @PACKAGE_LIBS@ @NEON_LIBS@ --- NEW FILE: webdav.h --- #define WEBDAV_SUCCESS 0 /* Request succeeded */ #define WEBDAV_ERROR_INIT 1 /* Could not init 'neon' library */ #define WEBDAV_ERROR_CONNECT 2 /* Could not connect to server */ #define WEBDAV_ERROR_RESSOURCE 3 /* Cannot read or write file */ #define WEBDAV_ERROR_FILE_NOT_FOUND 4 /* Local file not found */ #define WEBDAV_ERROR_INVALID_PARAMETER 5 /* Parameter not in valid range */ #define WEBDAV_ERROR_OUT_OF_MEMORY 6 /* Out of memory */ /* Download a file from a server */ int webdav_download(char* filename, char* url, char* username, char* password); /* Upload a file to a server */ int webdav_upload(char* filename, char* url, char* username, char* password); Index: Makefile.in =================================================================== RCS file: /cvsroot/multisync/multisync/plugins/sunbird_plugin/src/Attic/Makefile.in,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- Makefile.in 4 Feb 2005 09:50:55 -0000 1.1.2.1 +++ Makefile.in 7 Mar 2005 01:51:33 -0000 1.1.2.2 @@ -100,8 +100,13 @@ libsunbird_plugin_la_SOURCES = \ tools.c tools.h \ - sunbird_plugin.c sunbird_plugin.h + sunbird_plugin.c sunbird_plugin.h \ + webdav.c webdav.h + +NEON_LIBS = `neon-config --libs` + +libsunbird_plugin_la_LIBADD = @PACKAGE_LIBS@ @NEON_LIBS@ subdir = src mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h @@ -109,8 +114,8 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libsunbird_plugin_la_LDFLAGS = -libsunbird_plugin_la_LIBADD = -am_libsunbird_plugin_la_OBJECTS = tools.lo sunbird_plugin.lo +libsunbird_plugin_la_DEPENDENCIES = +am_libsunbird_plugin_la_OBJECTS = tools.lo sunbird_plugin.lo webdav.lo libsunbird_plugin_la_OBJECTS = $(am_libsunbird_plugin_la_OBJECTS) DEFS = @DEFS@ @@ -121,7 +126,7 @@ depcomp = $(SHELL) $(top_srcdir)/../../depcomp am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/sunbird_plugin.Plo \ -@AMDEP_TRUE@ ./$(DEPDIR)/tools.Plo +@AMDEP_TRUE@ ./$(DEPDIR)/tools.Plo ./$(DEPDIR)/webdav.Plo COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ @@ -182,6 +187,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sunbird_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/webdav.Plo@am__quote@ distclean-depend: -rm -rf ./$(DEPDIR) @@ -358,8 +364,6 @@ mostlyclean-generic mostlyclean-libtool tags uninstall \ uninstall-am uninstall-info-am uninstall-libLTLIBRARIES - -#libbackup_plugin_la_LIBADD = @PACKAGE_LIBS@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Index: tools.c =================================================================== RCS file: /cvsroot/multisync/multisync/plugins/sunbird_plugin/src/Attic/tools.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -d -r1.1.2.2 -r1.1.2.3 --- tools.c 6 Mar 2005 01:30:49 -0000 1.1.2.2 +++ tools.c 7 Mar 2005 01:51:33 -0000 1.1.2.3 @@ -165,6 +165,7 @@ int read_icalendar_file(char* filename, GList **entries_ptr) { + int num_entries = 0; int buf_size = 4096, len; char buf[buf_size]; FILE* f; @@ -203,6 +204,7 @@ { char *uid, *last_modified, *dtend, *x_sourcefile, *x_deleted, *vcal; + num_entries++; g_string_append(cur_entry->data, "\nEND:VEVENT\nEND:VCALENDAR\n"); vcal = cur_entry->data->str; @@ -217,7 +219,8 @@ { cur_entry->id = g_string_new(uid); g_free(uid); - } + } else + printf("WARNING: %i. entry in %s has no UID\n", num_entries, filename); if (last_modified) { @@ -315,6 +318,8 @@ { char *line, *begin_vevent = NULL; char *curpos = calendar->str; + + printf("patching calendar (change_type: %i)\n", change_type); while (*curpos) { @@ -332,6 +337,8 @@ if (strcmp(line, "END:VCALENDAR") == 0) { /* We must insert new stuff right before this last line */ + printf("end of calendar at %i\n", curpos-calendar->str); + if (change_type == SYNC_OBJ_MODIFIED || change_type == SYNC_OBJ_ADDED) { int insertpos = curpos - calendar->str; @@ -341,22 +348,40 @@ g_string_insert(calendar, insertpos, "\r\n"); g_string_insert(calendar, insertpos, stripped_data->str); g_string_free(stripped_data, TRUE); - return; // We are finished } + + printf("done patching calendar\n"); + return; } if (strcmp(line, "BEGIN:VEVENT") == 0) + { + printf("begin of vevent at %i\n", curpos-calendar->str); begin_vevent = curpos; + } if (strcmp(line, "END:VEVENT") == 0) { - char* event_id; - int len = curpos+strlen(curpos)-begin_vevent; + char *event_id, *nlpos; + int len = curpos-begin_vevent+strlen("END:VEVENT"); char* vcard = (char*)g_malloc0((len+1)*sizeof(char)); vcard[len] = 0; memcpy(vcard, begin_vevent, len); + printf("end of vevent at %i\n", curpos-calendar->str); + + /* sync_get_key_data() does not work when value for data is on the next line, */ + /* so just remove the newlines and the space to get the UID. */ + nlpos = strstr(vcard, "UID\r\n :"); + if (nlpos) + { + /* Remove the '\r\n ' */ + int ofs = nlpos+6-vcard; + memmove(nlpos+3, nlpos+6, len-ofs+1); // also copy the null-byte at the end + } + event_id = sync_get_key_data(vcard, "UID"); + if (event_id) { if (strcmp(event_id,id) == 0) @@ -365,13 +390,13 @@ int end_pos = (curpos - calendar->str) + strlen(line) + 2; /* Skip additional \r\n */ printf("Found event with ID %s, removing old instance\n", id); g_string_erase(calendar, begin_pos, end_pos-begin_pos); - curpos = calendar->str + begin_pos; + pos2 = calendar->str + begin_pos; } g_free(event_id); } else { - printf("ERROR: VEVENT has no ID!?\n"); + printf("ERROR: VEVENT has no ID!\n*** Dumping data: ***\n%s\n*** End dump ***\n", vcard); } g_free(vcard); @@ -381,6 +406,8 @@ g_free(line); curpos = pos2; } + + printf("ERROR: EOF while trying to patch calendar (no END:VCALENDAR found)!\n"); } GString* create_new_uid() Index: Makefile =================================================================== RCS file: /cvsroot/multisync/multisync/plugins/sunbird_plugin/src/Attic/Makefile,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -d -r1.1.2.2 -r1.1.2.3 --- Makefile 6 Mar 2005 01:30:49 -0000 1.1.2.2 +++ Makefile 7 Mar 2005 01:51:33 -0000 1.1.2.3 @@ -100,8 +100,13 @@ libsunbird_plugin_la_SOURCES = \ tools.c tools.h \ - sunbird_plugin.c sunbird_plugin.h + sunbird_plugin.c sunbird_plugin.h \ + webdav.c webdav.h + +NEON_LIBS = `neon-config --libs` + +libsunbird_plugin_la_LIBADD = -pthread -Wl,--export-dynamic -L/usr/X11R6/lib -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lxml2 -lpthread -lz -lgnomecanvas-2 -lgnome-2 -lpopt -lart_lgpl_2 -lpangoft2-1.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -lXrandr -lXi -lXinerama -lXext -latk-1.0 -lgdk_pixbuf-2.0 -lXcursor -lpangoxft-1.0 -lXft -lfreetype -lXrender -lfontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lbonobo-2 -lgconf-2 -lgnomevfs-2 -lbonobo-activation -lORBit-2 -lgobject-2.0 -lgthread-2.0 -lm -lgmodule-2.0 -ldl -lglib-2.0 -L/usr/local/lib -lneon -lz -L/usr/kerberos/lib -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lxml2 -lz -lpthread -lm subdir = src mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h @@ -109,8 +114,8 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libsunbird_plugin_la_LDFLAGS = -libsunbird_plugin_la_LIBADD = -am_libsunbird_plugin_la_OBJECTS = tools.lo sunbird_plugin.lo +libsunbird_plugin_la_DEPENDENCIES = +am_libsunbird_plugin_la_OBJECTS = tools.lo sunbird_plugin.lo webdav.lo libsunbird_plugin_la_OBJECTS = $(am_libsunbird_plugin_la_OBJECTS) DEFS = -DHAVE_CONFIG_H @@ -121,7 +126,7 @@ depcomp = $(SHELL) $(top_srcdir)/../../depcomp am__depfiles_maybe = depfiles DEP_FILES = ./$(DEPDIR)/sunbird_plugin.Plo \ - ./$(DEPDIR)/tools.Plo + ./$(DEPDIR)/tools.Plo ./$(DEPDIR)/webdav.Plo COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ @@ -129,7 +134,7 @@ CCLD = $(CC) LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CFLAGS = -g -O2 +CFLAGS = -g -O2 -I/usr/local/include/neon -DNEON_ZLIB DIST_SOURCES = $(libsunbird_plugin_la_SOURCES) DIST_COMMON = Makefile.am Makefile.in SOURCES = $(libsunbird_plugin_la_SOURCES) @@ -182,6 +187,7 @@ include ./$(DEPDIR)/sunbird_plugin.Plo include ./$(DEPDIR)/tools.Plo +include ./$(DEPDIR)/webdav.Plo distclean-depend: -rm -rf ./$(DEPDIR) @@ -358,8 +364,6 @@ mostlyclean-generic mostlyclean-libtool tags uninstall \ uninstall-am uninstall-info-am uninstall-libLTLIBRARIES - -#libbackup_plugin_la_LIBADD = -pthread -Wl,--export-dynamic -L/usr/X11R6/lib -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lxml2 -lpthread -lz -lgnomecanvas-2 -lgnome-2 -lpopt -lart_lgpl_2 -lpangoft2-1.0 -lgtk-x11-2.0 -lgdk-x11-2.0 -lXrandr -lXi -lXinerama -lXext -latk-1.0 -lgdk_pixbuf-2.0 -lXcursor -lpangoxft-1.0 -lXft -lfreetype -lXrender -lfontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lbonobo-2 -lgconf-2 -lgnomevfs-2 -lbonobo-activation -lORBit-2 -lgobject-2.0 -lgthread-2.0 -lm -lgmodule-2.0 -ldl -lglib-2.0 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: --- NEW FILE: webdav.c --- #include "webdav.h" #include <neon/ne_socket.h> #include <neon/ne_session.h> #include <neon/ne_request.h> static char auth_username[100]; static char auth_password[100]; static int neon_initialized = 0; static int webdav_server_auth(void* userdata, const char *realm, int attempts, char *username, char *password) { strcpy(username, auth_username); strcpy(password, auth_password); return attempts; } static int init_neon() { if (!neon_initialized) neon_initialized = (ne_sock_init() == 0); return neon_initialized; } static int webdav_spliturl(char* url, char* server, char* path) { char *p1, *p2; p1 = strstr(url, "://"); if (!p1) return 0; p1 += 3; p2 = strstr(p1, "/"); if (!p2) return 0; strcpy(server, p1); server[p2-p1] = 0; strcpy(path, p2); return 1; } int webdav_download(char* filename, char* url, char* username, char* password) { char server[256], path[256]; int result; ne_session* sess; ne_request* req; FILE* f; if (strlen(url) > 255 || strlen(username) > 99 || strlen(password) > 99) return WEBDAV_ERROR_INVALID_PARAMETER; if (!webdav_spliturl(url, server, path)) return WEBDAV_ERROR_INVALID_PARAMETER; f = fopen(filename, "w"); if (!f) return WEBDAV_ERROR_FILE_NOT_FOUND; strcpy(auth_username, username); strcpy(auth_password, password); if (!init_neon()) return WEBDAV_ERROR_INIT; sess = ne_session_create("http", server, 80); if (!sess) return WEBDAV_ERROR_CONNECT; ne_set_server_auth(sess, webdav_server_auth, 0); result = ne_get(sess, path, fileno(f)) ? WEBDAV_ERROR_RESSOURCE : WEBDAV_SUCCESS; fclose(f); ne_session_destroy(sess); return result; } int webdav_upload(char* filename, char* url, char* username, char* password) { char server[256], path[256], *buf; int result; int filesize; ne_session* sess; ne_request* req; FILE* f; if (strlen(url) > 255 || strlen(username) > 99 || strlen(password) > 99) return WEBDAV_ERROR_INVALID_PARAMETER; if (!webdav_spliturl(url, server, path)) return WEBDAV_ERROR_INVALID_PARAMETER; f = fopen(filename, "r"); if (!f) return WEBDAV_ERROR_FILE_NOT_FOUND; fseek(f, 0, SEEK_END); filesize = ftell(f); rewind(f); buf = (char*)malloc(filesize); if (!buf) { fclose(f); return WEBDAV_ERROR_OUT_OF_MEMORY; } fread(buf, 1, filesize, f); fclose(f); strcpy(auth_username, username); strcpy(auth_password, password); if (!init_neon()) return WEBDAV_ERROR_INIT; sess = ne_session_create("http", server, 80); if (!sess) { free(buf); return WEBDAV_ERROR_CONNECT; } ne_set_server_auth(sess, webdav_server_auth, 0); req = ne_request_create(sess, "PUT", path); ne_set_request_body_buffer(req, buf, filesize); if (ne_request_dispatch(req) != 0) { ne_request_destroy(req); ne_session_destroy(sess); free(buf); return WEBDAV_ERROR_RESSOURCE; } result = ne_get_status(req)->code; ne_request_destroy(req); ne_session_destroy(sess); free(buf); if (result < 200 || result > 299) return WEBDAV_ERROR_RESSOURCE; else return WEBDAV_SUCCESS; } |