diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile.am | 6 | ||||
-rw-r--r-- | tools/idevicebackup.c | 133 | ||||
-rw-r--r-- | tools/idevicebackup2.c | 261 |
3 files changed, 267 insertions, 133 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am index 19b2f92..20003aa 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,11 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = $(GLOBAL_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(openssl_CFLAGS) $(LFS_CFLAGS) AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) $(openssl_LIBS) -bin_PROGRAMS = idevice_id ideviceinfo idevicepair idevicesyslog ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate - -if HAVE_GLIB2 -bin_PROGRAMS += idevicebackup idevicebackup2 -endif +bin_PROGRAMS = idevice_id ideviceinfo idevicepair idevicesyslog ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate idevicebackup idevicebackup2 ideviceinfo_SOURCES = ideviceinfo.c ideviceinfo_CFLAGS = $(AM_CFLAGS) diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c index f744e70..25f8014 100644 --- a/tools/idevicebackup.c +++ b/tools/idevicebackup.c @@ -29,7 +29,6 @@ #include <errno.h> #include <stdlib.h> #include <signal.h> -#include <glib.h> #ifdef HAVE_OPENSSL #include <openssl/sha.h> #else @@ -222,10 +221,63 @@ static void notify_cb(const char *notification, void *userdata) } } +static char *str_toupper(char* str) +{ + char *res = strdup(str); + int i; + for (i = 0; i < strlen(res); i++) { + res[i] = toupper(res[i]); + } + return res; +} + +char* build_path(const char* elem, ...) +{ + if (!elem) return NULL; + va_list args; + int len = strlen(elem)+1; + va_start(args, elem); + char *arg = va_arg(args, char*); + while (arg) { + len += strlen(arg)+1; + arg = va_arg(args, char*); + } + va_end(args); + + char* out = (char*)malloc(len); + strcpy(out, elem); + + va_start(args, elem); + arg = va_arg(args, char*); + while (arg) { + strcat(out, "/"); + strcat(out, arg); + arg = va_arg(args, char*); + } + va_end(args); + return out; +} + +static char* format_size_for_display(uint64_t size) +{ + char buf[32]; + double sz; + if (size >= 1000000000LL) { + sz = ((double)size / 1000000000.0f); + sprintf(buf, "%0.1f GB", sz); + } else if (size >= 1000000LL) { + sz = ((double)size / 1000000.0f); + sprintf(buf, "%0.1f MB", sz); + } else if (size >= 1000LL) { + sz = ((double)size / 1000.0f); + sprintf(buf, "%0.1f kB", sz); + } + return strdup(buf); +} + static plist_t mobilebackup_factory_info_plist_new() { /* gather data from lockdown */ - GTimeVal tv = {0, 0}; plist_t value_node = NULL; plist_t root_node = NULL; char *uuid = NULL; @@ -251,8 +303,7 @@ static plist_t mobilebackup_factory_info_plist_new() if (value_node) plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); - g_get_current_time(&tv); - plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, tv.tv_usec)); + plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(time(NULL), 0)); value_node = plist_dict_get_item(root_node, "ProductType"); plist_dict_insert_item(ret, "Product Type", plist_copy(value_node)); @@ -268,7 +319,7 @@ static plist_t mobilebackup_factory_info_plist_new() plist_dict_insert_item(ret, "Target Identifier", plist_new_string(uuid)); /* uppercase */ - uuid_uppercase = g_ascii_strup(uuid, -1); + uuid_uppercase = str_toupper(uuid); plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); free(uuid_uppercase); free(uuid); @@ -285,15 +336,13 @@ static plist_t mobilebackup_factory_info_plist_new() static void mobilebackup_info_update_last_backup_date(plist_t info_plist) { - GTimeVal tv = {0, 0}; plist_t node = NULL; if (!info_plist) return; - g_get_current_time(&tv); node = plist_dict_get_item(info_plist, "Last Backup Date"); - plist_set_date_val(node, tv.tv_sec, tv.tv_usec); + plist_set_date_val(node, time(NULL), 0); node = NULL; } @@ -396,11 +445,13 @@ static int plist_strcmp(plist_t node, const char *str) return ret; } -static gchar *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension) +static char *mobilebackup_build_path(const char *backup_directory, const char *name, const char *extension) { - gchar *filename = g_strconcat(name, extension, NULL); - gchar *path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, filename, NULL); - g_free(filename); + char* filename = (char*)malloc(strlen(name)+strlen(extension)+1); + strcpy(filename, name); + strcat(filename, extension); + char *path = build_path(backup_directory, filename, NULL); + free(filename); return path; } @@ -409,7 +460,7 @@ static void mobilebackup_write_status(const char *path, int status) struct stat st; plist_t status_plist = plist_new_dict(); plist_dict_insert_item(status_plist, "Backup Success", plist_new_bool(status)); - gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); + char *file_path = mobilebackup_build_path(path, "Status", ".plist"); if (stat(file_path, &st) == 0) remove(file_path); @@ -419,17 +470,17 @@ static void mobilebackup_write_status(const char *path, int status) plist_free(status_plist); status_plist = NULL; - g_free(file_path); + free(file_path); } static int mobilebackup_read_status(const char *path) { int ret = -1; plist_t status_plist = NULL; - gchar *file_path = mobilebackup_build_path(path, "Status", ".plist"); + char *file_path = mobilebackup_build_path(path, "Status", ".plist"); plist_read_from_filename(&status_plist, file_path); - g_free(file_path); + free(file_path); if (!status_plist) { printf("Could not read Status.plist!\n"); return ret; @@ -510,14 +561,14 @@ static int mobilebackup_info_is_current_device(plist_t info) static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, const char *hash) { int ret = 0; - gchar *path = mobilebackup_build_path(backup_directory, hash, ".mddata"); + char *path = mobilebackup_build_path(backup_directory, hash, ".mddata"); printf("Removing \"%s\" ", path); if (!remove( path )) ret = 1; else ret = 0; - g_free(path); + free(path); if (!ret) return ret; @@ -529,7 +580,7 @@ static int mobilebackup_delete_backup_file_by_hash(const char *backup_directory, else ret = 0; - g_free(path); + free(path); return ret; } @@ -666,9 +717,9 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const hash_ok = 1; } - g_free(domain); - g_free(version); - g_free(destpath); + free(domain); + free(version); + free(destpath); if (!hash_ok) { printf("\r\n"); @@ -680,7 +731,7 @@ static int mobilebackup_check_file_integrity(const char *backup_directory, const printf("\n"); res = 0; } - g_free(data_hash); + free(data_hash); plist_free(mdinfo); return res; } @@ -841,7 +892,7 @@ int main(int argc, char *argv[]) char *info_path = mobilebackup_build_path(backup_directory, "Info", ".plist"); if (cmd == CMD_RESTORE) { if (stat(info_path, &st) != 0) { - g_free(info_path); + free(info_path); printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found.\n", backup_directory); return -1; } @@ -1010,7 +1061,7 @@ int main(int argc, char *argv[]) info_plist = mobilebackup_factory_info_plist_new(); plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); } - g_free(info_path); + free(info_path); plist_free(info_plist); info_plist = NULL; @@ -1060,7 +1111,7 @@ int main(int argc, char *argv[]) char *filename_mddata = NULL; char *filename_source = NULL; char *format_size = NULL; - gboolean is_manifest = FALSE; + int is_manifest = 0; uint8_t b = 0; /* process series of DLSendFile messages */ @@ -1085,9 +1136,9 @@ int main(int argc, char *argv[]) node = plist_dict_get_item(node_tmp, "BackupTotalSizeKey"); if (node) { plist_get_uint_val(node, &backup_total_size); - format_size = g_format_size_for_display(backup_total_size); + format_size = format_size_for_display(backup_total_size); printf("Backup data requires %s on the disk.\n", format_size); - g_free(format_size); + free(format_size); } } @@ -1102,7 +1153,7 @@ int main(int argc, char *argv[]) if (node) { plist_get_bool_val(node, &b); } - is_manifest = (b == 1) ? TRUE: FALSE; + is_manifest = (b == 1) ? 1 : 0; if ((hunk_index == 0) && (!is_manifest)) { /* get source filename */ @@ -1115,17 +1166,17 @@ int main(int argc, char *argv[]) plist_get_uint_val(node, &file_size); backup_real_size += file_size; - format_size = g_format_size_for_display(backup_real_size); + format_size = format_size_for_display(backup_real_size); printf("(%s", format_size); - g_free(format_size); + free(format_size); - format_size = g_format_size_for_display(backup_total_size); + format_size = format_size_for_display(backup_total_size); printf("/%s): ", format_size); - g_free(format_size); + free(format_size); - format_size = g_format_size_for_display(file_size); + format_size = format_size_for_display(file_size); printf("Receiving file %s (%s)... \n", filename_source, format_size); - g_free(format_size); + free(format_size); if (filename_source) free(filename_source); @@ -1148,7 +1199,7 @@ int main(int argc, char *argv[]) node = plist_dict_get_item(node_tmp, "BackupFileInfo"); plist_write_to_filename(node, filename_mdinfo, PLIST_FORMAT_BINARY); - g_free(filename_mdinfo); + free(filename_mdinfo); } file_index++; @@ -1182,7 +1233,7 @@ int main(int argc, char *argv[]) free(buffer); buffer = NULL; - g_free(filename_mddata); + free(filename_mddata); } if ((!is_manifest)) { @@ -1220,7 +1271,7 @@ files_out: /* remove any atomic Manifest.plist.tmp */ if (manifest_path) - g_free(manifest_path); + free(manifest_path); manifest_path = mobilebackup_build_path(backup_directory, "Manifest", ".plist.tmp"); if (stat(manifest_path, &st) == 0) @@ -1330,12 +1381,12 @@ files_out: } else { printf("Could not get AuthSignature from manifest!\n"); } - g_free(auth_sig); + free(auth_sig); } else if (auth_ver) { printf("Unknown AuthVersion '%s', cannot verify AuthSignature\n", auth_ver); } plist_from_bin(bin, (uint32_t)binsize, &backup_data); - g_free(bin); + free(bin); } if (!backup_data) { printf("Could not read plist from Manifest.plist Data key!\n"); @@ -1615,7 +1666,7 @@ files_out: do_post_notification(NP_SYNC_DID_FINISH); } if (manifest_path) - g_free(manifest_path); + free(manifest_path); } else { printf("ERROR: Could not start service %s.\n", MOBILEBACKUP_SERVICE_NAME); lockdownd_client_free(client); diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c index 5d067bf..6e35abd 100644 --- a/tools/idevicebackup2.c +++ b/tools/idevicebackup2.c @@ -25,13 +25,9 @@ #include <errno.h> #include <stdlib.h> #include <signal.h> -#include <glib.h> -#include <glib/gstdio.h> #include <unistd.h> - -#if !GLIB_CHECK_VERSION(2,25,0) -typedef struct stat GStatBuf; -#endif +#include <dirent.h> +#include <libgen.h> #include <libimobiledevice/libimobiledevice.h> #include <libimobiledevice/lockdown.h> @@ -39,6 +35,8 @@ typedef struct stat GStatBuf; #include <libimobiledevice/notification_proxy.h> #include <libimobiledevice/afc.h> +#include <endianness.h> + #define MOBILEBACKUP2_SERVICE_NAME "com.apple.mobilebackup2" #define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" @@ -156,10 +154,95 @@ static void mobilebackup_afc_get_file_contents(const char *filename, char **data afc_file_close(afc, f); } +static char *str_toupper(char* str) +{ + char *res = strdup(str); + int i; + for (i = 0; i < strlen(res); i++) { + res[i] = toupper(res[i]); + } + return res; +} + +static int __mkdir(const char* path, int mode) +{ +#ifdef WIN32 + return mkdir(path); +#else + return mkdir(path, mode); +#endif +} + +int mkdir_with_parents(const char *dir, int mode) +{ + if (!dir) return -1; + if (__mkdir(dir, mode) == 0) { + return 0; + } else { + if (errno == EEXIST) return 0; + } + int res; + char *parent = strdup(dir); + parent = dirname(parent); + if (parent) { + res = mkdir_with_parents(parent, mode); + } else { + res = -1; + } + free(parent); + if (res == 0) { + mkdir_with_parents(dir, mode); + } + return res; +} + +char* build_path(const char* elem, ...) +{ + if (!elem) return NULL; + va_list args; + int len = strlen(elem)+1; + va_start(args, elem); + char *arg = va_arg(args, char*); + while (arg) { + len += strlen(arg)+1; + arg = va_arg(args, char*); + } + va_end(args); + + char* out = (char*)malloc(len); + strcpy(out, elem); + + va_start(args, elem); + arg = va_arg(args, char*); + while (arg) { + strcat(out, "/"); + strcat(out, arg); + arg = va_arg(args, char*); + } + va_end(args); + return out; +} + +static char* format_size_for_display(uint64_t size) +{ + char buf[32]; + double sz; + if (size >= 1000000000LL) { + sz = ((double)size / 1000000000.0f); + sprintf(buf, "%0.1f GB", sz); + } else if (size >= 1000000LL) { + sz = ((double)size / 1000000.0f); + sprintf(buf, "%0.1f MB", sz); + } else if (size >= 1000LL) { + sz = ((double)size / 1000.0f); + sprintf(buf, "%0.1f kB", sz); + } + return strdup(buf); +} + static plist_t mobilebackup_factory_info_plist_new() { /* gather data from lockdown */ - GTimeVal tv = {0, 0}; plist_t value_node = NULL; plist_t root_node = NULL; char *uuid = NULL; @@ -189,8 +272,7 @@ static plist_t mobilebackup_factory_info_plist_new() if (value_node) plist_dict_insert_item(ret, "IMEI", plist_copy(value_node)); - g_get_current_time(&tv); - plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(tv.tv_sec, 0)); + plist_dict_insert_item(ret, "Last Backup Date", plist_new_date(time(NULL), 0)); value_node = plist_dict_get_item(root_node, "PhoneNumber"); if (value_node && (plist_get_node_type(value_node) == PLIST_STRING)) { @@ -215,7 +297,7 @@ static plist_t mobilebackup_factory_info_plist_new() plist_dict_insert_item(ret, "Target Type", plist_new_string("Device")); /* uppercase */ - uuid_uppercase = g_ascii_strup(uuid, -1); + uuid_uppercase = str_toupper(uuid); plist_dict_insert_item(ret, "Unique Identifier", plist_new_string(uuid_uppercase)); free(uuid_uppercase); free(uuid); @@ -246,9 +328,11 @@ static plist_t mobilebackup_factory_info_plist_new() for (i = 0; itunesfiles[i]; i++) { data_buf = NULL; data_size = 0; - gchar *fname = g_strconcat("/iTunes_Control/iTunes/", itunesfiles[i], NULL); + char *fname = (char*)malloc(strlen("/iTunes_Control/iTunes/") + strlen(itunesfiles[i]) + 1); + strcpy(fname, "/iTunes_Control/iTunes/"); + strcat(fname, itunesfiles[i]); mobilebackup_afc_get_file_contents(fname, &data_buf, &data_size); - g_free(fname); + free(fname); if (data_buf) { plist_dict_insert_item(files, itunesfiles[i], plist_new_data(data_buf, data_size)); free(data_buf); @@ -358,10 +442,10 @@ static int mb2_status_check_snapshot_state(const char *path, const char *uuid, c { int ret = -1; plist_t status_plist = NULL; - gchar *file_path = g_build_path(G_DIR_SEPARATOR_S, path, uuid, "Status.plist", NULL); + char *file_path = build_path(path, uuid, "Status.plist", NULL); plist_read_from_filename(&status_plist, file_path); - g_free(file_path); + free(file_path); if (!status_plist) { printf("Could not read Status.plist!\n"); return ret; @@ -486,7 +570,7 @@ static void print_progress_real(double progress, int flush) static void print_progress(uint64_t current, uint64_t total) { - gchar *format_size = NULL; + char *format_size = NULL; double progress = ((double)current/(double)total)*100; if (progress < 0) return; @@ -496,12 +580,12 @@ static void print_progress(uint64_t current, uint64_t total) print_progress_real((double)progress, 0); - format_size = g_format_size_for_display(current); + format_size = format_size_for_display(current); PRINT_VERBOSE(1, " (%s", format_size); - g_free(format_size); - format_size = g_format_size_for_display(total); + free(format_size); + format_size = format_size_for_display(total); PRINT_VERBOSE(1, "/%s) ", format_size); - g_free(format_size); + free(format_size); fflush(stdout); if (progress == 100) @@ -534,7 +618,7 @@ static int mb2_handle_send_file(const char *backup_dir, const char *path, plist_ uint32_t nlen = 0; uint32_t pathlen = strlen(path); uint32_t bytes = 0; - gchar *localfile = g_build_path(G_DIR_SEPARATOR_S, backup_dir, path, NULL); + char *localfile = build_path(backup_dir, path, NULL); char buf[32768]; struct stat fst; @@ -549,7 +633,7 @@ static int mb2_handle_send_file(const char *backup_dir, const char *path, plist_ mobilebackup2_error_t err; /* send path length */ - nlen = GUINT32_TO_BE(pathlen); + nlen = htobe32(pathlen); err = mobilebackup2_send_raw(mobilebackup2, (const char*)&nlen, sizeof(nlen), &bytes); if (err != MOBILEBACKUP2_E_SUCCESS) { goto leave_proto_err; @@ -578,9 +662,9 @@ static int mb2_handle_send_file(const char *backup_dir, const char *path, plist_ total = fst.st_size; - gchar *format_size = g_format_size_for_display(total); + char *format_size = format_size_for_display(total); PRINT_VERBOSE(1, "Sending '%s' (%s)\n", path, format_size); - g_free(format_size); + free(format_size); if (total == 0) { errcode = 0; @@ -598,7 +682,7 @@ static int mb2_handle_send_file(const char *backup_dir, const char *path, plist_ do { length = ((total-sent) < (off_t)sizeof(buf)) ? (uint32_t)total-sent : (uint32_t)sizeof(buf); /* send data size (file size + 1) */ - nlen = GUINT32_TO_BE(length+1); + nlen = htobe32(length+1); memcpy(buf, &nlen, sizeof(nlen)); buf[4] = CODE_FILE_DATA; err = mobilebackup2_send_raw(mobilebackup2, (const char*)buf, 5, &bytes); @@ -634,7 +718,7 @@ leave: if (errcode == 0) { result = 0; nlen = 1; - nlen = GUINT32_TO_BE(nlen); + nlen = htobe32(nlen); memcpy(buf, &nlen, 4); buf[4] = CODE_SUCCESS; mobilebackup2_send_raw(mobilebackup2, buf, 5, &bytes); @@ -646,7 +730,7 @@ leave: mb2_multi_status_add_file_error(*errplist, path, errno_to_device_error(errcode), errdesc); length = strlen(errdesc); - nlen = GUINT32_TO_BE(length+1); + nlen = htobe32(length+1); memcpy(buf, &nlen, 4); buf[4] = CODE_ERROR_LOCAL; slen = 5; @@ -664,7 +748,7 @@ leave: leave_proto_err: if (f) fclose(f); - g_free(localfile); + free(localfile); return result; } @@ -726,7 +810,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) char buf[32768]; char *fname = NULL; char *dname = NULL; - gchar *bname = NULL; + char *bname = NULL; char code = 0; char last_code = 0; plist_t node = NULL; @@ -748,7 +832,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) break; r = 0; mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r); - nlen = GUINT32_FROM_BE(nlen); + nlen = be32toh(nlen); if (nlen == 0) { // we're done here break; @@ -769,7 +853,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) dname[r] = 0; nlen = 0; mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r); - nlen = GUINT32_FROM_BE(nlen); + nlen = be32toh(nlen); if (nlen == 0) { printf("ERROR: %s: zero-length backup filename!\n", __func__); break; @@ -785,8 +869,8 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) } fname[r] = 0; if (bname != NULL) - g_free(bname); - bname = g_build_path(G_DIR_SEPARATOR_S, backup_dir, fname, NULL); + free(bname); + bname = build_path(backup_dir, fname, NULL); free(fname); nlen = 0; mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r); @@ -794,7 +878,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) printf("ERROR: %s: could not receive code length!\n", __func__); break; } - nlen = GUINT32_FROM_BE(nlen); + nlen = be32toh(nlen); last_code = code; code = 0; mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r); @@ -837,7 +921,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) break; nlen = 0; mobilebackup2_receive_raw(mobilebackup2, (char*)&nlen, 4, &r); - nlen = GUINT32_FROM_BE(nlen); + nlen = be32toh(nlen); if (nlen > 0) { last_code = code; mobilebackup2_receive_raw(mobilebackup2, &code, 1, &r); @@ -880,7 +964,7 @@ static int mb2_handle_receive_files(plist_t message, const char *backup_dir) /* clean up */ if (bname != NULL) - g_free(bname); + free(bname); if (dname != NULL) free(dname); @@ -905,37 +989,37 @@ static void mb2_handle_list_directory(plist_t message, const char *backup_dir) return; } - gchar *path = g_build_path(G_DIR_SEPARATOR_S, backup_dir, str, NULL); + char *path = build_path(backup_dir, str, NULL); free(str); plist_t dirlist = plist_new_dict(); - GDir *cur_dir = g_dir_open(path, 0, NULL); + DIR* cur_dir = opendir(path); if (cur_dir) { - gchar *dir_file; - while ((dir_file = (gchar *)g_dir_read_name(cur_dir))) { - gchar *fpath = g_build_filename(path, dir_file, NULL); + struct dirent* ep; + while ((ep = readdir(cur_dir))) { + char *fpath = build_path(path, ep->d_name, NULL); if (fpath) { plist_t fdict = plist_new_dict(); - GStatBuf st; - g_stat(fpath, &st); + struct stat st; + stat(fpath, &st); const char *ftype = "DLFileTypeUnknown"; - if (g_file_test(fpath, G_FILE_TEST_IS_DIR)) { + if (S_ISDIR(st.st_mode)) { ftype = "DLFileTypeDirectory"; - } else if (g_file_test(fpath, G_FILE_TEST_IS_REGULAR)) { + } else if (S_ISREG(st.st_mode)) { ftype = "DLFileTypeRegular"; } plist_dict_insert_item(fdict, "DLFileType", plist_new_string(ftype)); plist_dict_insert_item(fdict, "DLFileSize", plist_new_uint(st.st_size)); plist_dict_insert_item(fdict, "DLFileModificationDate", plist_new_date(st.st_mtime, 0)); - plist_dict_insert_item(dirlist, dir_file, fdict); - g_free(fpath); + plist_dict_insert_item(dirlist, ep->d_name, fdict); + free(fpath); } } - g_dir_close(cur_dir); + closedir(cur_dir); } - g_free(path); + free(path); /* TODO error handling */ mobilebackup2_error_t err = mobilebackup2_send_status_response(mobilebackup2, 0, NULL, dirlist); @@ -955,24 +1039,24 @@ static void mb2_handle_make_directory(plist_t message, const char *backup_dir) char *errdesc = NULL; plist_get_string_val(dir, &str); - gchar *newpath = g_build_path(G_DIR_SEPARATOR_S, backup_dir, str, NULL); - g_free(str); + char *newpath = build_path(backup_dir, str, NULL); + free(str); - if (g_mkdir_with_parents(newpath, 0755) < 0) { + if (mkdir_with_parents(newpath, 0755) < 0) { errdesc = strerror(errno); if (errno != EEXIST) { printf("mkdir: %s (%d)\n", errdesc, errno); } errcode = errno_to_device_error(errno); } - g_free(newpath); + free(newpath); mobilebackup2_error_t err = mobilebackup2_send_status_response(mobilebackup2, errcode, errdesc, NULL); if (err != MOBILEBACKUP2_E_SUCCESS) { printf("Could not send status response, error %d\n", err); } } -static void mb2_copy_file_by_path(const gchar *src, const gchar *dst) +static void mb2_copy_file_by_path(const char *src, const char *dst) { FILE *from, *to; char buf[BUFSIZ]; @@ -1004,43 +1088,45 @@ static void mb2_copy_file_by_path(const gchar *src, const gchar *dst) } } -static void mb2_copy_directory_by_path(const gchar *src, const gchar *dst) +static void mb2_copy_directory_by_path(const char *src, const char *dst) { if (!src || !dst) { return; } + struct stat st; + /* if src does not exist */ - if (!g_file_test(src, G_FILE_TEST_EXISTS)) { + if ((stat(src, &st) < 0) || !S_ISDIR(st.st_mode)) { printf("ERROR: Source directory does not exist '%s': %s (%d)\n", src, strerror(errno), errno); return; } /* if dst directory does not exist */ - if (!g_file_test(dst, G_FILE_TEST_IS_DIR)) { + if ((stat(dst, &st) < 0) || !S_ISDIR(st.st_mode)) { /* create it */ - if (g_mkdir_with_parents(dst, 0755) < 0) { + if (mkdir_with_parents(dst, 0755) < 0) { printf("ERROR: Unable to create destination directory '%s': %s (%d)\n", dst, strerror(errno), errno); return; } } /* loop over src directory contents */ - GDir *cur_dir = g_dir_open(src, 0, NULL); + DIR *cur_dir = opendir(src); if (cur_dir) { - gchar *dir_file; - while ((dir_file = (gchar *)g_dir_read_name(cur_dir))) { - gchar *srcpath = g_build_filename(src, dir_file, NULL); - gchar *dstpath = g_build_filename(dst, dir_file, NULL); + struct dirent* ep; + while ((ep = readdir(cur_dir))) { + char *srcpath = build_path(src, ep->d_name, NULL); + char *dstpath = build_path(dst, ep->d_name, NULL); if (srcpath && dstpath) { /* copy file */ mb2_copy_file_by_path(srcpath, dstpath); - g_free(srcpath); - g_free(dstpath); + free(srcpath); + free(dstpath); } } - g_dir_close(cur_dir); + closedir(cur_dir); } } @@ -1196,10 +1282,10 @@ int main(int argc, char *argv[]) } /* backup directory must contain an Info.plist */ - gchar *info_path = g_build_path(G_DIR_SEPARATOR_S, backup_directory, uuid, "Info.plist", NULL); + char *info_path = build_path(backup_directory, uuid, "Info.plist", NULL); if (cmd == CMD_RESTORE) { if (stat(info_path, &st) != 0) { - g_free(info_path); + free(info_path); printf("ERROR: Backup directory \"%s\" is invalid. No Info.plist found for UUID %s.\n", backup_directory, uuid); return -1; } @@ -1328,9 +1414,9 @@ checkpoint: PRINT_VERBOSE(1, "Starting backup...\n"); /* make sure backup device sub-directory exists */ - gchar *devbackupdir = g_build_path(G_DIR_SEPARATOR_S, backup_directory, uuid, NULL); - g_mkdir(devbackupdir, 0755); - g_free(devbackupdir); + char *devbackupdir = build_path(backup_directory, uuid, NULL); + __mkdir(devbackupdir, 0755); + free(devbackupdir); /* TODO: check domain com.apple.mobile.backup key RequiresEncrypt and WillEncrypt with lockdown */ /* TODO: verify battery on AC enough battery remaining */ @@ -1343,7 +1429,7 @@ checkpoint: info_plist = mobilebackup_factory_info_plist_new(); remove(info_path); plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); - g_free(info_path); + free(info_path); plist_free(info_plist); info_plist = NULL; @@ -1493,9 +1579,9 @@ checkpoint: char *str = NULL; plist_get_string_val(val, &str); if (str) { - gchar *newpath = g_build_path(G_DIR_SEPARATOR_S, backup_directory, str, NULL); - g_free(str); - gchar *oldpath = g_build_path(G_DIR_SEPARATOR_S, backup_directory, key, NULL); + char *newpath = build_path(backup_directory, str, NULL); + free(str); + char *oldpath = build_path(backup_directory, key, NULL); remove(newpath); if (rename(oldpath, newpath) < 0) { @@ -1504,8 +1590,8 @@ checkpoint: errdesc = strerror(errno); break; } - g_free(oldpath); - g_free(newpath); + free(oldpath); + free(newpath); } free(key); key = NULL; @@ -1534,14 +1620,14 @@ checkpoint: char *str = NULL; plist_get_string_val(val, &str); if (str) { - gchar *newpath = g_build_path(G_DIR_SEPARATOR_S, backup_directory, str, NULL); - g_free(str); + char *newpath = build_path(backup_directory, str, NULL); + free(str); if (remove(newpath) < 0) { printf("Could not remove '%s': %s (%d)\n", newpath, strerror(errno), errno); errcode = errno_to_device_error(errno); errdesc = strerror(errno); } - g_free(newpath); + free(newpath); } } } @@ -1560,23 +1646,24 @@ checkpoint: plist_get_string_val(srcpath, &src); plist_get_string_val(dstpath, &dst); if (src && dst) { - gchar *oldpath = g_build_path(G_DIR_SEPARATOR_S, backup_directory, src, NULL); - gchar *newpath = g_build_path(G_DIR_SEPARATOR_S, backup_directory, dst, NULL); + char *oldpath = build_path(backup_directory, src, NULL); + char *newpath = build_path(backup_directory, dst, NULL); + struct stat st; PRINT_VERBOSE(1, "Copying '%s' to '%s'\n", src, dst); /* check that src exists */ - if (g_file_test(oldpath, G_FILE_TEST_IS_DIR)) { + if ((stat(oldpath, &st) == 0) && S_ISDIR(st.st_mode)) { mb2_copy_directory_by_path(oldpath, newpath); - } else if (g_file_test(oldpath, G_FILE_TEST_IS_REGULAR)) { + } else if ((stat(oldpath, &st) == 0) && S_ISREG(st.st_mode)) { mb2_copy_file_by_path(oldpath, newpath); } - g_free(newpath); - g_free(oldpath); + free(newpath); + free(oldpath); } - g_free(src); - g_free(dst); + free(src); + free(dst); } err = mobilebackup2_send_status_response(mobilebackup2, errcode, errdesc, plist_new_dict()); |