+static bool can_restore_all_files(UAContext *ua)
+{
+ alist *lst;
+ if (ua->cons) {
+ lst = ua->cons->ACL_lists[Directory_ACL];
+ /* ACL not defined, or the first entry is not *all* */
+ /* TODO: See if we search for *all* in all the list */
+ if (!lst || strcasecmp((char*)lst->get(0), "*all*") != 0) {
+ return false;
+ }
+ if (!lst || strcasecmp((char *)lst->get(0), "*all*") != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool ask_for_fileregex(UAContext *ua, RESTORE_CTX *rx)
+{
+ bool can_restore=can_restore_all_files(ua);
+
+ if (can_restore && find_arg(ua, NT_("all")) >= 0) { /* if user enters all on command line */
+ return true; /* select everything */
+ }
+
+ ua->send_msg(_("\n\nFor one or more of the JobIds selected, no files were found,\n"
+ "so file selection is not possible.\n"
+ "Most likely your retention policy pruned the files.\n"));
+
+ if (!can_restore) {
+ ua->error_msg(_("\nThe current Console has UserId or Directory restrictions. "
+ "The full restore is not allowed.\n"));
+ return false;
+ }
+
+ if (get_yesno(ua, _("\nDo you want to restore all the files? (yes|no): "))) {
+ if (ua->pint32_val == 1)
+ return true;
+ while (get_cmd(ua, _("\nRegexp matching files to restore? (empty to abort): "))) {
+ if (ua->cmd[0] == '\0') {
+ break;
+ } else {
+ regex_t *fileregex_re = NULL;
+ int rc;
+ char errmsg[500] = "";
+
+ fileregex_re = (regex_t *)bmalloc(sizeof(regex_t));
+ rc = regcomp(fileregex_re, ua->cmd, REG_EXTENDED|REG_NOSUB);
+ if (rc != 0) {
+ regerror(rc, fileregex_re, errmsg, sizeof(errmsg));
+ }
+ regfree(fileregex_re);
+ free(fileregex_re);
+ if (*errmsg) {
+ ua->send_msg(_("Regex compile error: %s\n"), errmsg);
+ } else {
+ rx->fileregex = bstrdup(ua->cmd);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/* Walk on the delta_list of a TREE_NODE item and insert all parts
+ * TODO: Optimize for bootstrap creation, remove recursion
+ * 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0
+ * should insert as
+ * 0, 1, 2, 3, 4, 5, 6
+ */
+static void add_delta_list_findex(RESTORE_CTX *rx, struct delta_list *lst)
+{
+ if (lst == NULL) {
+ return;
+ }
+ if (lst->next) {
+ add_delta_list_findex(rx, lst->next);
+ }
+ add_findex(rx->bsr_list, lst->JobId, lst->FileIndex);
+}
+
+/*
+ * This is a list of all the files (components) that the
+ * user has requested for restore. It is requested by
+ * the plugin (for now hard coded only for VSS).
+ * In the future, this will be requested by a RestoreObject
+ * and the plugin name will be sent to the FD.
+ */
+static bool write_component_file(UAContext *ua, RESTORE_CTX *rx, char *fname)
+{
+ int fd;
+ if (!rx->component_fd) {
+ Mmsg(rx->component_fname, "%s/%s.restore.sel.XXXXXX", working_directory, my_name);
+ fd = mkstemp(rx->component_fname);
+ if (fd < 0) {
+ berrno be;
+ ua->error_msg(_("Unable to create component file %s. ERR=%s\n"),
+ rx->component_fname, be.bstrerror());
+ return false;
+ }
+ rx->component_fd = fdopen(fd, "w+");
+ if (!rx->component_fd) {
+ berrno be;
+ ua->error_msg(_("Unable to fdopen component file %s. ERR=%s\n"),
+ rx->component_fname, be.bstrerror());
+ return false;
+ }
+ }
+ fprintf(rx->component_fd, "%s\n", fname);
+ if (ferror(rx->component_fd)) {
+ ua->error_msg(_("Error writing component file.\n"));
+ fclose(rx->component_fd);
+ unlink(rx->component_fname);
+ rx->component_fd = NULL;
+ return false;
+ }
+ return true;
+}
+