+(defun package-admin-install-function-mswindows (file pkg-dir buffer)
+ "Install function for mswindows."
+ (let ((default-directory (file-name-as-directory pkg-dir)))
+ (unless (file-directory-p default-directory)
+ (make-directory default-directory t))
+ (call-process "minitar" nil buffer t file)))
+
+(defun package-admin-default-install-function (filename pkg-dir buffer)
+ "Default function to install a package.
+Install package FILENAME into directory PKG-DIR, with any messages output
+to BUFFER."
+ (let* ((pkg-dir (file-name-as-directory pkg-dir))
+ (default-directory pkg-dir)
+ (filename (expand-file-name filename)))
+ (unless (file-directory-p pkg-dir)
+ (make-directory pkg-dir t))
+ ;; Don't assume GNU tar.
+ (if (shell-command (concat "gunzip -c " filename " | tar xvf -") buffer)
+ 0
+ 1)
+ ))
+
+; (call-process "add-big-package.sh"
+; nil
+; buffer
+; t
+; ;; rest of command line follows
+; package-admin-xemacs file pkg-dir))
+
+(defun package-admin-get-install-dir (package pkg-dir &optional mule-related)
+ "If PKG-DIR is non-nil return that,
+else return the current location of the package if it is already installed
+or return a location appropriate for the package otherwise."
+ (if pkg-dir
+ pkg-dir
+ (let ((package-feature (intern-soft (concat
+ (symbol-name package) "-autoloads")))
+ autoload-dir)
+ (when (and (not (eq package 'unknown))
+ (featurep package-feature)
+ (setq autoload-dir (feature-file package-feature))
+ (setq autoload-dir (file-name-directory autoload-dir))
+ (member autoload-dir (append early-package-load-path late-package-load-path)))
+ ;; Find the corresponding entry in late-package
+ (setq pkg-dir
+ (car-safe (member-if (lambda (h)
+ (string-match (concat "^" (regexp-quote h))
+ autoload-dir))
+ (append (cdr early-packages) late-packages)))))
+ (if pkg-dir
+ pkg-dir
+ ;; Ok we need to guess
+ (if mule-related
+ (package-admin-get-install-dir 'mule-base nil nil)
+ (if (eq package 'xemacs-base)
+ (car (last late-packages))
+ (package-admin-get-install-dir 'xemacs-base nil nil)))))))
+
+
+
+(defun package-admin-get-manifest-file (pkg-topdir package)
+ "Return the name of the MANIFEST file for package PACKAGE.
+Note that PACKAGE is a symbol, and not a string."
+ (let (dir)
+ (setq dir (expand-file-name "pkginfo" pkg-topdir))
+ (expand-file-name (concat "MANIFEST." (symbol-name package)) dir)
+ ))
+
+(defun package-admin-check-manifest (pkg-outbuf pkg-topdir)
+ "Check for a MANIFEST.<package> file in the package distribution.
+If it doesn't exist, create and write one.
+PKG-OUTBUF is the buffer that holds the output from `tar', and PKG-TOPDIR
+is the top-level directory under which the package was installed."
+ (let ( (manifest-buf " *pkg-manifest*")
+ old-case-fold-search regexp package-name pathname regexps)
+ ;; Save and restore the case-fold-search status.
+ ;; We do this in case we have to screw with it (as it the case of
+ ;; case-insensitive filesystems such as MS Windows).
+ (setq old-case-fold-search case-fold-search)
+ (unwind-protect
+ (save-excursion ;; Probably redundant.
+ (set-buffer (get-buffer pkg-outbuf)) ;; Probably already the
+ ;; current buffer.
+ (goto-char (point-min))
+
+ ;; Make filenames case-insensitive, if necessary
+ (if (eq system-type 'windows-nt)
+ (setq case-fold-search t))
+
+ ;; We really should compute the regexp.
+ ;; However, directory-sep-char is currently broken, but we need
+ ;; functional code *NOW*.
+ (setq regexp "\\bpkginfo[\\/]MANIFEST\\...*")
+
+ ;; Look for the manifest.
+ (if (not (re-search-forward regexp nil t))
+ (progn
+ ;; We didn't find a manifest. Make one.
+
+ ;; Yuk. We weren't passed the package name, and so we have
+ ;; to dig for it. Look for it as the subdirectory name below
+ ;; "lisp", "man", "info", or "etc".
+ ;; Here, we don't use a single regexp because we want to search
+ ;; the directories for a package name in a particular order.
+ ;; The problem is that packages could have directories like
+ ;; "etc/sounds/" or "etc/photos/" and we don't want to get
+ ;; these confused with the actual package name (although, in
+ ;; the case of "etc/sounds/", it's probably correct).
+ (if (catch 'done
+ (let ( (dirs '("lisp" "info" "man" "etc")) rexp)
+ (while dirs
+ (setq rexp (concat "\\b" (car dirs)
+ "[\\/]\\([^\\/]+\\)[\//]"))
+ (if (re-search-forward rexp nil t)
+ (throw 'done t))
+ (setq dirs (cdr dirs))
+ )))
+ (progn
+ (setq package-name (buffer-substring (match-beginning 1)
+ (match-end 1)))
+
+ ;; Get and erase the manifest buffer
+ (setq manifest-buf (get-buffer-create manifest-buf))
+ (buffer-disable-undo manifest-buf)
+ (erase-buffer manifest-buf)
+
+ ;; Now, scan through the output buffer, looking for
+ ;; file and directory names.
+ (goto-char (point-min))
+ ;; for each line ...
+ (while (< (point) (point-max))
+ (beginning-of-line)
+ (setq pathname nil)
+
+ ;; scan through the regexps, looking for a pathname
+ (if (catch 'found-path
+ (setq regexps package-admin-tar-filename-regexps)
+ (while regexps
+ (if (looking-at (car regexps))
+ (progn
+ (setq pathname
+ (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))
+ (throw 'found-path t)
+ ))
+ (setq regexps (cdr regexps))
+ )
+ )
+ (progn
+ ;; found a pathname -- add it to the manifest
+ ;; buffer
+ (save-excursion
+ (set-buffer manifest-buf)
+ (goto-char (point-max))
+ (insert pathname "\n")
+ )
+ ))
+ (forward-line 1)
+ )
+
+ ;; Processed all lines.
+ ;; Now, create the file, pkginfo/MANIFEST.<pkgname>
+
+ ;; We use `expand-file-name' instead of `concat',
+ ;; for portability.
+ (setq pathname (expand-file-name "pkginfo"
+ pkg-topdir))
+ ;; Create pkginfo, if necessary
+ (if (not (file-directory-p pathname))
+ (make-directory pathname))
+ (setq pathname (expand-file-name
+ (concat "MANIFEST." package-name)
+ pathname))
+ (save-excursion
+ (set-buffer manifest-buf)
+ ;; Put the files in sorted order
+ (sort-lines nil (point-min) (point-max))
+ ;; Write the file.
+ ;; Note that using `write-region' *BYPASSES* any check
+ ;; to see if XEmacs is currently editing/visiting the
+ ;; file.
+ (write-region (point-min) (point-max) pathname)
+ )
+ (kill-buffer manifest-buf)
+ )
+ (progn
+ ;; We can't determine the package name from an extracted
+ ;; file in the tar output buffer.
+ ))
+ ))
+ )
+ ;; Restore old case-fold-search status
+ (setq case-fold-search old-case-fold-search))
+ ))
+