| 
					
				 | 
			
			
				@@ -1353,6 +1353,34 @@ For more examples, see the system specific constants 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			(string :tag "Command") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			(function :tag "Function"))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defcustom org-resource-download-policy 'prompt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "The policy applied to requests to obtain remote resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+This affects keywords like #+setupfile and #+incude on export, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+`org-persist-write:url',and `org-attach-url' in non-interactive 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Emacs sessions. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+This recognises four possible values: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- t, remote resources should always be downloaded. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- prompt, you will be prompted to download resources nt considered safe. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- safe, only resources considered safe will be downloaded. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- nil, never download remote resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+A resource is considered safe if it matches one of the patterns 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+in `org-safe-remote-resources'." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :group 'org 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :type '(choice (const :tag "Always download remote resources" t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 (const :tag "Prompt before downloading an unsafe resource" prompt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 (const :tag "Only download resources considered safe" safe) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 (const :tag "Never download any resources" nil))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defcustom org-safe-remote-resources nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "A list of regexp patterns matching safe URIs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+URI regexps are applied to both URLs and Org files requesting 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+remote resources." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :group 'org 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  :type '(list regexp)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defcustom org-open-non-existing-files nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   "Non-nil means `org-open-file' opens non-existing files. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4468,21 +4496,25 @@ is available.  This option applies only if FILE is a URL." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (cond 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      (cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      (is-url 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      (with-current-buffer (url-retrieve-synchronously file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	(goto-char (point-min)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	;; Move point to after the url-retrieve header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	(search-forward "\n\n" nil :move) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	;; Search for the success code only in the url-retrieve header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	(if (save-excursion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	      (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	    ;; Update the cache `org--file-cache' and return contents. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	    (puthash file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		     (buffer-substring-no-properties (point) (point-max)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		     org--file-cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  (funcall (if noerror #'message #'user-error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		   "Unable to fetch file from %S" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		   file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	  nil))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (if (org--should-fetch-remote-resource-p file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (with-current-buffer (url-retrieve-synchronously file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (goto-char (point-min)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ;; Move point to after the url-retrieve header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (search-forward "\n\n" nil :move) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ;; Search for the success code only in the url-retrieve header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (if (save-excursion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  (re-search-backward "HTTP.*\\s-+200\\s-OK" nil :noerror)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ;; Update the cache `org--file-cache' and return contents. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (puthash file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         (buffer-substring-no-properties (point) (point-max)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         org--file-cache) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              (funcall (if noerror #'message #'user-error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       "Unable to fetch file from %S" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              nil)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (funcall (if noerror #'message #'user-error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "The remote resource %S is considered unsafe, and will not be downloaded." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 file))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      (t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (with-temp-buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         (condition-case nil 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4495,6 +4527,74 @@ is available.  This option applies only if FILE is a URL." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		    file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	   nil))))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org--should-fetch-remote-resource-p (uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Return non-nil if the URI should be fetched." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (or (eq org-resource-download-policy t) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (org--safe-remote-resource-p uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (and (eq org-resource-download-policy 'prompt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           (org--confirm-resource-safe uri)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org--safe-remote-resource-p (uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Return non-nil if URI is considered safe. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+This checks every pattern in `org-safe-remote-resources', and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+returns non-nil if any of them match." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (let ((uri-patterns org-safe-remote-resources) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (file-uri (and buffer-file-name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       (concat "file://" (file-truename buffer-file-name)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        match-p) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (while (and (not match-p) uri-patterns) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (setq match-p (or (string-match-p (car uri-patterns) uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        (and file-uri (string-match-p (car uri-patterns) file-uri))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            uri-patterns (cdr uri-patterns))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    match-p)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org--confirm-resource-safe (uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Ask the user if URI should be considered safe, returning non-nil if so." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (unless noninteractive 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (let ((current-file (and buffer-file-name (file-truename buffer-file-name))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (buf (get-buffer-create "*Org Remote Resource*"))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ;; Set up the contents of the *Org Remote Resource* buffer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (with-current-buffer buf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (erase-buffer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (insert "An org-mode document would like to download " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize uri 'face '(:inherit org-link :weight normal)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ", which is not considered safe.\n\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "Do you want to download this?  You can type\n " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize "!" 'face 'success) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " to download this resource, and permanantly mark it as safe.\n " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize "f" 'face 'success) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " to download this resource, and permanantly mark all resources in " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize current-file 'face 'fixed-pitch-serif) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " as safe.\n " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize "y" 'face 'warning) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " to download this resource, just this once.\n " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (propertize "n" 'face 'error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                " to skip this resource.\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (setq-local cursor-type nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (set-buffer-modified-p nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (goto-char (point-min))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ;; Display the buffer and read a choice. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (save-window-excursion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (pop-to-buffer buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (let* ((exit-chars '(?y ?n ?! ?f ?\s)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               (prompt (format "Please type y, n, f, or !%s: " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               (if (< (line-number-at-pos (point-max)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      (window-body-height)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 ", or C-v/M-v to scroll"))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               char) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (setq char (read-char-choice prompt exit-chars)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (when (memq char '(?! ?f)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (customize-push-and-save 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             'org-safe-remote-resources 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             (list (rx string-start 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       (literal 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        (if (and (= char ?f) current-file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            (concat "file://" current-file) uri)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       string-end)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (prog1 (memq char '(?! ?\s ?y ?f)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (quit-window t))))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun org-extract-log-state-settings (x) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   "Extract the log state setting from a TODO keyword string. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 This will extract info from a string like \"WAIT(w@/!)\"." 
			 |