(linenum→info "unix/slp.c:2238")

gauche/0.8.12/src/gauche-install.in

    1: ;;;
    2: ;;; install - Generic installation utility
    3: ;;;  
    4: ;;;   Copyright (c) 2004-2006 Shiro Kawai, All rights reserved.
    5: ;;;   
    6: ;;;   Redistribution and use in source and binary forms, with or without
    7: ;;;   modification, are permitted provided that the following conditions
    8: ;;;   are met:
    9: ;;;   
   10: ;;;   1. Redistributions of source code must retain the above copyright
   11: ;;;      notice, this list of conditions and the following disclaimer.
   12: ;;;  
   13: ;;;   2. Redistributions in binary form must reproduce the above copyright
   14: ;;;      notice, this list of conditions and the following disclaimer in the
   15: ;;;      documentation and/or other materials provided with the distribution.
   16: ;;;  
   17: ;;;   3. Neither the name of the authors nor the names of its contributors
   18: ;;;      may be used to endorse or promote products derived from this
   19: ;;;      software without specific prior written permission.
   20: ;;;  
   21: ;;;   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22: ;;;   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23: ;;;   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24: ;;;   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   25: ;;;   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26: ;;;   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   27: ;;;   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   28: ;;;   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   29: ;;;   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   30: ;;;   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   31: ;;;   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32: ;;;  
   33: ;;;  $Id: gauche-install.in,v 1.3 2006/04/07 21:33:45 shirok Exp $
   34: ;;;
   35: 
   36: ;; This is intended to replace 'install' program, in order to avoid
   37: ;; variations of system's install program.  Although most 'install'
   38: ;; programs have various extensions, we can't reliably use those
   39: ;; extended features since we don't know such extended install program
   40: ;; is avilable on the target system.  Assuming minimum featured install
   41: ;; program makes makefile messy.
   42: 
   43: (use srfi-1)
   44: (use srfi-2)
   45: (use gauche.parseopt)
   46: (use gauche.parameter)
   47: (use file.util)
   48: 
   49: (define (p . args) (for-each print args))
   50: 
   51: (define (usage)
   52:   (p "Usage: gauche-install [options] file dest             (1st format)"
   53:      "       gauche-install [options] file ... directory    (2nd format)"
   54:      "       gauche-install -d [options] directory ...      (3rd format)"
   55:      "       gauche-install -T directory [options] file ... (4th format)"
   56:      "       gauche-install -U directory [options] file ... (5th format)"
   57:      "Options:"
   58:      "  -T, --target=DIR  : installs files to the DIR, creating paths if needed."
   59:      "                      Partial path of files are preserved. (4th format only)"
   60:      "  -U, --uninstall=DIR : Reverse of -T, e.g. removes files from its"
   61:      "                      destination."
   62:      "  -S, --srcdir=DIR  : look for files within DIR; useful if VPATH is used"
   63:      "      --shebang=PATH : adds #!PATH before the file contents."
   64:      "                       useful to install scripts."
   65:      "  -d, --directory   : creates directories.  (3rd format only)."
   66:      "  -m, --mode=MODE   : change mode of the installed file."
   67:      "  -o, --owner=OWNER : change owner of the installed file (root only)."
   68:      "  -g, --group=GROUP : change owner of the installed file (root only)."
   69:      "  -v, --verbose     : work verbosely"
   70:      "  -n, --dry-run     : just prints what actions to be done."
   71:      )
   72:   (exit 0))
   73: 
   74: (define verbose (make-parameter #f))
   75: (define dry-run (make-parameter #f))
   76: 
   77: (define-syntax do-it
   78:   (syntax-rules ()
   79:     ((_ mesg . actions)
   80:      (begin (when (and (verbose) mesg) (print mesg))
   81:             (unless (dry-run) . actions)))))
   82: 
   83: (define (app-errorf fmt msg)
   84:   (format (current-error-port) fmt msg)
   85:   (newline (current-error-port))
   86:   (exit 1))
   87: 
   88: (define (ensure-directory path . args)
   89:   (if (file-exists? path)
   90:     (unless (file-is-directory? path)
   91:       (app-errorf "non-directory file gets in my way: ~s" path))
   92:     (let-optionals* args ((mode #f)
   93:                           (owner #f)
   94:                           (group #f))
   95:       (do-it #`"creating directory ,path"
   96:              (guard (e (else (app-errorf "can't create directory: ~s"
   97:                                          (ref e 'message))))
   98:                (when (make-directory* path)
   99:                  (when mode (sys-chmod path mode))
  100:                  (when (or owner group)
  101:                    (sys-chown path
  102:                               (->ugid sys-user-name->uid owner "user")
  103:                               (->ugid sys-group-name->gid group "group")))))
  104:              ))))
  105: 
  106: ;; user/group -> uid/gid
  107: (define (->ugid str->id arg type)
  108:   (cond ((not arg) -1)
  109:         ((integer? arg) arg)
  110:         ((and (string? arg) (str->id arg)))
  111:         (else (app-errorf #`"bad ,type name: ~a" arg))))
  112: 
  113: ;; find source path
  114: (define (ensure-src file srcdir)
  115:   (or (and-let* ((srcdir)
  116:                  (srcpath (build-path srcdir file))
  117:                  ((file-exists? srcpath)))
  118:         srcpath)
  119:       file))
  120: 
  121: ;; copy, possibly with appending prelude
  122: (define (cp src dest prelude)
  123:   (if prelude
  124:     (receive (out name) (sys-mkstemp src)
  125:       (display prelude out)
  126:       (call-with-input-file src
  127:         (lambda (in)
  128:           (copy-port in out :unit 65536)))
  129:       (close-output-port out)
  130:       (move-file name dest :if-exists :supersede))
  131:     (copy-file src dest :if-exists :supersede :safe #t)))
  132: 
  133: ;; standard install
  134: (define (install src dest prelude mode owner group)
  135:   (do-it #`"installing ,src to ,dest"
  136:          (and (cp src dest prelude)
  137:               (sys-chmod dest mode)
  138:               (when (or owner group)
  139:                 (sys-chown dest
  140:                            (->ugid sys-user-name->uid owner "user")
  141:                            (->ugid sys-group-name->gid group "group"))))))
  142: 
  143: 
  144: ;; Entry point
  145: (define (main args)
  146:   (let-args (cdr args)
  147:       ((#f      "c")        ;; ignore for historical reason
  148:        (mkdir   "d|directory")
  149:        (mode    "m|mode=s" #o755 => (cut string->number <> 8))
  150:        (owner   "o|owner=s")
  151:        (group   "g|group=s")
  152:        (srcdir  "S|srcdir=s")
  153:        (target  "T|target=s")
  154:        (utarget "U|uninstall=s")
  155:        (shebang "shebang=s")
  156:        (verb    "v")
  157:        (dry     "n|dry-run")
  158:        (#f      "h|help" => usage)
  159:        (else (opt . _) (print "Unknown option : " opt) (usage))
  160:        . args)
  161: 
  162:     (parameterize ((verbose (or verb dry))
  163:                    (dry-run dry))
  164:       (when shebang (set! shebang #`"#!,shebang\n"))
  165:       (cond
  166:        (mkdir  (for-each (cut ensure-directory <> mode owner group) args))
  167:        (target (for-each (lambda (src)
  168:                            (let1 dst (build-path target src)
  169:                              (ensure-directory (sys-dirname dst))
  170:                              (install (ensure-src src srcdir) dst
  171:                                       shebang mode owner group)))
  172:                          args))
  173:        (utarget (for-each (lambda (src)
  174:                             (sys-unlink (build-path utarget src)))
  175:                           args))
  176:        (else
  177:         (case (length args)
  178:           ((0) (usage))
  179:           ((1) #f)          ;; no-op
  180:           ((2) ;; file to file or file to dir
  181:            (let* ((src (car args))
  182:                   (dst (if (file-is-directory? (cadr args))
  183:                          (build-path (cadr args) (sys-basename src))
  184:                          (cadr args))))
  185:              (ensure-directory (sys-dirname dst))
  186:              (install (ensure-src src srcdir) dst
  187:                       shebang mode owner group)))
  188:           (else
  189:            (let ((target (car (last-pair args))))
  190:              (for-each (lambda (src)
  191:                          (let1 dst (build-path target (sys-basename src))
  192:                            (ensure-directory (sys-dirname dst))
  193:                            (install (ensure-src src srcdir) dst
  194:                                     shebang mode owner group)))
  195:                        (drop-right args 1)))))))
  196:       ))
  197:   0)
  198: 
  199: ;; Local variables:
  200: ;; mode: scheme
  201: ;; end:
Syntax (Markdown)