comparison lisp/files.el @ 84440:2311575b5cd3

(file-modes-char-to-who, file-modes-char-to-right) (file-modes-rights-to-number): Auxiliary functions for symbolic to numeric notation of file modes. (file-modes-symbolic-to-number): New. Convert symbolic modes to its numeric value. (read-file-modes): New. Read either an octal value of a file mode or a symbolic value, and return its numeric value.
author Michaël Cadilhac <michael.cadilhac@lrde.org>
date Mon, 10 Sep 2007 09:51:25 +0000
parents d2159c231849
children 04f3172e88f3
comparison
equal deleted inserted replaced
84439:aed070a1f09b 84440:2311575b5cd3
5405 (setq buffer-file-name (concat "/:" buffer-file-name)) 5405 (setq buffer-file-name (concat "/:" buffer-file-name))
5406 res)) 5406 res))
5407 (t 5407 (t
5408 (apply operation arguments))))) 5408 (apply operation arguments)))))
5409 5409
5410 ;; Symbolic modes and read-file-modes.
5411
5412 (defun file-modes-char-to-who (char)
5413 "Convert CHAR to a who-mask from a symbolic mode notation.
5414 CHAR is in [ugoa] and represents the users on which rights are applied."
5415 (cond ((= char ?u) #o4700)
5416 ((= char ?g) #o2070)
5417 ((= char ?o) #o1007)
5418 ((= char ?a) #o7777)
5419 (t (error "%c: bad `who' character" char))))
5420
5421 (defun file-modes-char-to-right (char &optional from)
5422 "Convert CHAR to a right-mask from a symbolic mode notation.
5423 CHAR is in [rwxXstugo] and represents a right.
5424 If CHAR is in [Xugo], the value is extracted from FROM (or 0 if nil)."
5425 (or from (setq from 0))
5426 (cond ((= char ?r) #o0444)
5427 ((= char ?w) #o0222)
5428 ((= char ?x) #o0111)
5429 ((= char ?s) #o1000)
5430 ((= char ?t) #o6000)
5431 ;; Rights relative to the previous file modes.
5432 ((= char ?X) (if (= (logand from #o111) 0) 0 #o0111))
5433 ((= char ?u) (let ((uright (logand #o4700 from)))
5434 (+ uright (/ uright #o10) (/ uright #o100))))
5435 ((= char ?g) (let ((gright (logand #o2070 from)))
5436 (+ gright (/ gright #o10) (* gright #o10))))
5437 ((= char ?o) (let ((oright (logand #o1007 from)))
5438 (+ oright (* oright #o10) (* oright #o100))))
5439 (t (error "%c: bad right character" char))))
5440
5441 (defun file-modes-rights-to-number (rights who-mask &optional from)
5442 "Convert a right string to a right-mask from a symbolic modes notation.
5443 RIGHTS is the right string, it should match \"([+=-][rwxXstugo]+)+\".
5444 WHO-MASK is the mask number of the users on which the rights are to be applied.
5445 FROM (or 0 if nil) is the orginal modes of the file to be chmod'ed."
5446 (let* ((num-rights (or from 0))
5447 (list-rights (string-to-list rights))
5448 (op (pop list-rights)))
5449 (while (memq op '(?+ ?- ?=))
5450 (let ((num-right 0)
5451 char-right)
5452 (while (memq (setq char-right (pop list-rights))
5453 '(?r ?w ?x ?X ?s ?t ?u ?g ?o))
5454 (setq num-right
5455 (logior num-right
5456 (file-modes-char-to-right char-right num-rights))))
5457 (setq num-right (logand who-mask num-right)
5458 num-rights
5459 (cond ((= op ?+) (logior num-rights num-right))
5460 ((= op ?-) (logand num-rights (lognot num-right)))
5461 (t (logior (logand num-rights (lognot who-mask)) num-right)))
5462 op char-right)))
5463 num-rights))
5464
5465 (defun file-modes-symbolic-to-number (modes &optional from)
5466 "Convert symbolic file modes to numeric file modes.
5467 MODES is the string to convert, it should match
5468 \"[ugoa]*([+-=][rwxXstugo]+)+,...\".
5469 See (info \"(coreutils)File permissions\") for more information on this
5470 notation.
5471 FROM (or 0 if nil) is the orginal modes of the file to be chmod'ed."
5472 (save-match-data
5473 (let ((case-fold-search nil)
5474 (num-modes (or from 0)))
5475 (while (/= (string-to-char modes) 0)
5476 (if (string-match "^\\([ugoa]*\\)\\([+=-][rwxXstugo]+\\)+\\(,\\|\\)" modes)
5477 (let ((num-who (apply 'logior 0
5478 (mapcar 'file-modes-char-to-who
5479 (match-string 1 modes)))))
5480 (when (= num-who 0)
5481 (setq num-who (default-file-modes)))
5482 (setq num-modes
5483 (file-modes-rights-to-number (substring modes (match-end 1))
5484 num-who num-modes)
5485 modes (substring modes (match-end 3))))
5486 (error "Parse error in modes near `%s'" (substring modes 0))))
5487 num-modes)))
5488
5489 (defun read-file-modes (&optional prompt orig-file)
5490 "Read file modes in octal or symbolic notation.
5491 PROMPT is used as the prompt, default to `File modes (octal or symbolic): '.
5492 ORIG-FILE is the original file of which modes will be change."
5493 (let* ((modes (or (if orig-file (file-modes orig-file) 0)
5494 (error "File not found")))
5495 (value (read-string (or prompt "File modes (octal or symbolic): "))))
5496 (save-match-data
5497 (if (string-match "^[0-7]+" value)
5498 (string-to-number value 8)
5499 (file-modes-symbolic-to-number value modes)))))
5500
5501
5410 (define-key ctl-x-map "\C-f" 'find-file) 5502 (define-key ctl-x-map "\C-f" 'find-file)
5411 (define-key ctl-x-map "\C-r" 'find-file-read-only) 5503 (define-key ctl-x-map "\C-r" 'find-file-read-only)
5412 (define-key ctl-x-map "\C-v" 'find-alternate-file) 5504 (define-key ctl-x-map "\C-v" 'find-alternate-file)
5413 (define-key ctl-x-map "\C-s" 'save-buffer) 5505 (define-key ctl-x-map "\C-s" 'save-buffer)
5414 (define-key ctl-x-map "s" 'save-some-buffers) 5506 (define-key ctl-x-map "s" 'save-some-buffers)