static gboolean dl_sync_dir(mega_node* node, GFile* file, const gchar* remote_path) { GError *local_err = NULL; gchar* local_path = g_file_get_path(file); if (!g_file_query_exists(file, NULL)) { g_print("D %s\n", local_path); if (!opt_dryrun) { if (!g_file_make_directory(file, NULL, &local_err)) { g_printerr("ERROR: Can't create local directory %s: %s\n", local_path, local_err->message); g_clear_error(&local_err); return FALSE; } } } else { if (g_file_query_file_type(file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) != G_FILE_TYPE_DIRECTORY) { g_printerr("ERROR: Can't create local directory %s: file exists\n", local_path); return FALSE; } } // sync children GSList* children = mega_session_get_node_chilren(s, node), *i; for (i = children; i; i = i->next) { mega_node* child = i->data; gchar* child_remote_path = g_strconcat(remote_path, "/", child->name, NULL); GFile* child_file = g_file_get_child(file, child->name); if (child->type == MEGA_NODE_FILE) { dl_sync_file(child, child_file, child_remote_path); } else { dl_sync_dir(child, child_file, child_remote_path); } g_object_unref(child_file); g_free(child_remote_path); } g_slist_free(children); return TRUE; }
int main(int ac, char* av[]) { tool_init(&ac, &av, "- synchronize local and remote mega.nz directories", entries); if (!opt_local_path || !opt_remote_path) { g_printerr("ERROR: You must specify local and remote paths\n"); return 1; } s = tool_start_session(); if (!s) { tool_fini(NULL); return 1; } mega_session_watch_status(s, status_callback, NULL); // check remote dir existence mega_node* remote_dir = mega_session_stat(s, opt_remote_path); if (!remote_dir) { g_printerr("ERROR: Remote directory not found %s\n", opt_remote_path); goto err0; } else if (!mega_node_is_container(remote_dir)) { g_printerr("ERROR: Remote path must be a folder: %s\n", opt_remote_path); goto err0; } // check local dir existence GFile* local_file = g_file_new_for_path(opt_local_path); if (opt_download) { dl_sync_dir(remote_dir, local_file, opt_remote_path); } else { if (g_file_query_file_type(local_file, 0, NULL) != G_FILE_TYPE_DIRECTORY) { g_printerr("ERROR: Local directory not found %s\n", opt_local_path); goto err1; } up_sync_dir(local_file, local_file, opt_remote_path); mega_session_save(s, NULL); } g_object_unref(local_file); tool_fini(s); return 0; err1: g_object_unref(local_file); err0: tool_fini(s); return 1; }
int main(int ac, char* av[]) { GError *local_err = NULL; GRegex *file_regex, *folder_regex; gchar* key; gchar* handle; gint i; tool_init_bare(&ac, &av, "- download exported files from mega.co.nz", entries); if (!strcmp(opt_path, "-")) opt_noprogress = opt_stream = TRUE; if (ac < 2) { g_printerr("ERROR: No links specified for download!\n"); tool_fini(NULL); return 1; } if (opt_stream && ac != 2) { g_printerr("ERROR: Can't stream from multiple files!\n"); tool_fini(NULL); return 1; } // prepare link parsers file_regex = g_regex_new("^https?://mega.co.nz/#!([a-z0-9_-]{8})!([a-z0-9_-]{43})$", G_REGEX_CASELESS, 0, NULL); g_assert(file_regex != NULL); folder_regex = g_regex_new("^https?://mega.co.nz/#F!([a-z0-9_-]{8})!([a-z0-9_-]{22})$", G_REGEX_CASELESS, 0, NULL); g_assert(folder_regex != NULL); // create session s = mega_session_new(); mega_session_watch_status(s, status_callback, NULL); // process links for (i = 1; i < ac; i++) { GMatchInfo* m1 = NULL; GMatchInfo* m2 = NULL; key = NULL; handle = NULL; if (g_regex_match(file_regex, av[i], 0, &m1)) { handle = g_match_info_fetch(m1, 1); key = g_match_info_fetch(m1, 2); // perform download if (!mega_session_dl(s, handle, key, opt_stream ? NULL : opt_path, &local_err)) { if (!opt_noprogress) g_print("\r" ESC_CLREOL "\n"); g_printerr("ERROR: Download failed for '%s': %s\n", av[i], local_err->message); g_clear_error(&local_err); } else { if (!opt_noprogress) g_print("\r" ESC_CLREOL "Downloaded %s\n", cur_file); } } else if (g_regex_match(folder_regex, av[i], 0, &m2)) { if (opt_stream) { g_printerr("ERROR: Can't stream from a directory!\n"); if (m1) g_match_info_unref(m1); if (m2) g_match_info_unref(m2); tool_fini(s); return 1; } handle = g_match_info_fetch(m2, 1); key = g_match_info_fetch(m2, 2); // perform download if (!mega_session_open_exp_folder(s, handle, key, &local_err)) { g_printerr("ERROR: Can't open folder '%s': %s\n", av[i], local_err->message); g_clear_error(&local_err); } else { GSList* l = mega_session_ls(s, "/", FALSE); if (g_slist_length(l) == 1) { mega_node* root_node = l->data; GFile* local_dir = g_file_new_for_path(opt_path); if (g_file_query_file_type(local_dir, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) == G_FILE_TYPE_DIRECTORY) { dl_sync_dir(root_node, local_dir, root_node->path); } else { g_printerr("ERROR: %s must be a directory\n", opt_path); } } else { g_printerr("ERROR: EXP folder fs has multiple toplevel nodes? Weird!\n"); } } } else { g_printerr("WARNING: Skipping invalid Mega download link: %s\n", av[i]); } if (m1) g_match_info_unref(m1); if (m2) g_match_info_unref(m2); g_free(handle); g_free(key); } tool_fini(s); return 0; }