/[emacs]/emacs/lisp/net/tramp-smb.el
ViewVC logotype

Diff of /emacs/lisp/net/tramp-smb.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by kai, Wed Feb 5 21:03:36 2003 UTC revision 1.4 by kai, Fri Feb 28 18:28:47 2003 UTC
# Line 225  KEEP-DATE is not handled in case NEWNAME Line 225  KEEP-DATE is not handled in case NEWNAME
225          (error "copy-file: file %s already exists" newname))          (error "copy-file: file %s already exists" newname))
226    
227  ;      (with-parsed-tramp-file-name newname nil  ;      (with-parsed-tramp-file-name newname nil
228        (let (user host path)        (let (user host localname)
229          (with-parsed-tramp-file-name newname l          (with-parsed-tramp-file-name newname l
230            (setq user l-user host l-host path l-path))            (setq user l-user host l-host localname l-localname))
231          (save-excursion          (save-excursion
232            (let ((share (tramp-smb-get-share path))            (let ((share (tramp-smb-get-share localname))
233                  (file (tramp-smb-get-path path t)))                  (file (tramp-smb-get-localname localname t)))
234              (unless share              (unless share
235                (error "Target `%s' must contain a share name" filename))                (error "Target `%s' must contain a share name" filename))
236              (tramp-smb-maybe-open-connection user host share)              (tramp-smb-maybe-open-connection user host share)
# Line 250  KEEP-DATE is not handled in case NEWNAME Line 250  KEEP-DATE is not handled in case NEWNAME
250    (unless (file-exists-p directory)    (unless (file-exists-p directory)
251      (error "Cannot delete non-existing directory `%s'" directory))      (error "Cannot delete non-existing directory `%s'" directory))
252  ;  (with-parsed-tramp-file-name directory nil  ;  (with-parsed-tramp-file-name directory nil
253    (let (user host path)    (let (user host localname)
254      (with-parsed-tramp-file-name directory l      (with-parsed-tramp-file-name directory l
255        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
256      (save-excursion      (save-excursion
257        (let ((share (tramp-smb-get-share path))        (let ((share (tramp-smb-get-share localname))
258              (dir (tramp-smb-get-path (file-name-directory path) t))              (dir (tramp-smb-get-localname (file-name-directory localname) t))
259              (file (file-name-nondirectory path)))              (file (file-name-nondirectory localname)))
260          (tramp-smb-maybe-open-connection user host share)          (tramp-smb-maybe-open-connection user host share)
261          (if (and          (if (and
262               (tramp-smb-send-command user host (format "cd \"%s\"" dir))               (tramp-smb-send-command user host (format "cd \"%s\"" dir))
# Line 273  KEEP-DATE is not handled in case NEWNAME Line 273  KEEP-DATE is not handled in case NEWNAME
273    (unless (file-exists-p filename)    (unless (file-exists-p filename)
274      (error "Cannot delete non-existing file `%s'" filename))      (error "Cannot delete non-existing file `%s'" filename))
275  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
276    (let (user host path)    (let (user host localname)
277      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
278        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
279      (save-excursion      (save-excursion
280        (let ((share (tramp-smb-get-share path))        (let ((share (tramp-smb-get-share localname))
281              (dir (tramp-smb-get-path (file-name-directory path) t))              (dir (tramp-smb-get-localname (file-name-directory localname) t))
282              (file (file-name-nondirectory path)))              (file (file-name-nondirectory localname)))
283          (unless (file-exists-p filename)          (unless (file-exists-p filename)
284            (error "Cannot delete non-existing file `%s'" filename))            (error "Cannot delete non-existing file `%s'" filename))
285          (tramp-smb-maybe-open-connection user host share)          (tramp-smb-maybe-open-connection user host share)
# Line 297  KEEP-DATE is not handled in case NEWNAME Line 297  KEEP-DATE is not handled in case NEWNAME
297    "Like `directory-files' for tramp files."    "Like `directory-files' for tramp files."
298    (setq directory (directory-file-name (expand-file-name directory)))    (setq directory (directory-file-name (expand-file-name directory)))
299  ;  (with-parsed-tramp-file-name directory nil  ;  (with-parsed-tramp-file-name directory nil
300    (let (user host path)    (let (user host localname)
301      (with-parsed-tramp-file-name directory l      (with-parsed-tramp-file-name directory l
302        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
303      (save-excursion      (save-excursion
304        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
305               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
306               (entries (tramp-smb-get-file-entries user host share file)))               (entries (tramp-smb-get-file-entries user host share file)))
307          ;; Just the file names are needed          ;; Just the file names are needed
308          (setq entries (mapcar 'car entries))          (setq entries (mapcar 'car entries))
# Line 312  KEEP-DATE is not handled in case NEWNAME Line 312  KEEP-DATE is not handled in case NEWNAME
312                  (delete nil                  (delete nil
313                          (mapcar (lambda (x) (when (string-match match x) x))                          (mapcar (lambda (x) (when (string-match match x) x))
314                                  entries))))                                  entries))))
315          ;; Make absolute paths if necessary          ;; Make absolute localnames if necessary
316          (when full          (when full
317            (setq entries            (setq entries
318                  (mapcar (lambda (x)                  (mapcar (lambda (x)
# Line 331  KEEP-DATE is not handled in case NEWNAME Line 331  KEEP-DATE is not handled in case NEWNAME
331       (cons x (file-attributes       (cons x (file-attributes
332          (if full x (concat (file-name-as-directory directory) x)))))          (if full x (concat (file-name-as-directory directory) x)))))
333     (directory-files directory full match nosort)))     (directory-files directory full match nosort)))
334    
335  (defun tramp-smb-handle-file-attributes (filename &optional nonnumeric)  (defun tramp-smb-handle-file-attributes (filename &optional nonnumeric)
336    "Like `file-attributes' for tramp files.    "Like `file-attributes' for tramp files.
337  Optional argument NONNUMERIC means return user and group name  Optional argument NONNUMERIC means return user and group name
338  rather than as numbers."  rather than as numbers."
339  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
340    (let (user host path)    (let (user host localname)
341      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
342        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
343      (save-excursion      (save-excursion
344        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
345               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
346               (entries (tramp-smb-get-file-entries user host share file))               (entries (tramp-smb-get-file-entries user host share file))
347               (entry (and entries               (entry (and entries
348                           (assoc (file-name-nondirectory file) entries)))                           (assoc (file-name-nondirectory file) entries)))
# Line 368  rather than as numbers." Line 368  rather than as numbers."
368  (defun tramp-smb-handle-file-directory-p (filename)  (defun tramp-smb-handle-file-directory-p (filename)
369    "Like `file-directory-p' for tramp files."    "Like `file-directory-p' for tramp files."
370  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
371    (let  (user host path)    (let  (user host localname)
372      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
373        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
374      (save-excursion      (save-excursion
375        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
376               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
377               (entries (tramp-smb-get-file-entries user host share file))               (entries (tramp-smb-get-file-entries user host share file))
378               (entry (and entries               (entry (and entries
379                           (assoc (file-name-nondirectory file) entries))))                           (assoc (file-name-nondirectory file) entries))))
# Line 384  rather than as numbers." Line 384  rather than as numbers."
384  (defun tramp-smb-handle-file-exists-p (filename)  (defun tramp-smb-handle-file-exists-p (filename)
385    "Like `file-exists-p' for tramp files."    "Like `file-exists-p' for tramp files."
386  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
387    (let  (user host path)    (let  (user host localname)
388      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
389        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
390      (save-excursion      (save-excursion
391        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
392               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
393               (entries (tramp-smb-get-file-entries user host share file)))               (entries (tramp-smb-get-file-entries user host share file)))
394          (and entries          (and entries
395               (member (file-name-nondirectory file) (mapcar 'car entries))               (member (file-name-nondirectory file) (mapcar 'car entries))
# Line 399  rather than as numbers." Line 399  rather than as numbers."
399    "Like `file-local-copy' for tramp files."    "Like `file-local-copy' for tramp files."
400    (with-parsed-tramp-file-name filename nil    (with-parsed-tramp-file-name filename nil
401      (save-excursion      (save-excursion
402        (let ((share (tramp-smb-get-share path))        (let ((share (tramp-smb-get-share localname))
403              (file (tramp-smb-get-path path t))              (file (tramp-smb-get-localname localname t))
404              (tmpfil (tramp-make-temp-file)))              (tmpfil (tramp-make-temp-file)))
405          (unless (file-exists-p filename)          (unless (file-exists-p filename)
406            (error "Cannot make local copy of non-existing file `%s'" filename))            (error "Cannot make local copy of non-existing file `%s'" filename))
# Line 421  rather than as numbers." Line 421  rather than as numbers."
421  (defun tramp-smb-handle-file-name-all-completions (filename directory)  (defun tramp-smb-handle-file-name-all-completions (filename directory)
422    "Like `file-name-all-completions' for tramp files."    "Like `file-name-all-completions' for tramp files."
423  ;  (with-parsed-tramp-file-name directory nil  ;  (with-parsed-tramp-file-name directory nil
424    (let (user host path)    (let (user host localname)
425      (with-parsed-tramp-file-name directory l      (with-parsed-tramp-file-name directory l
426        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
427      (save-match-data      (save-match-data
428        (save-excursion        (save-excursion
429          (let* ((share (tramp-smb-get-share path))          (let* ((share (tramp-smb-get-share localname))
430                 (file (tramp-smb-get-path path nil))                 (file (tramp-smb-get-localname localname nil))
431                 (entries (tramp-smb-get-file-entries user host share file)))                 (entries (tramp-smb-get-file-entries user host share file)))
432    
433            (all-completions            (all-completions
# Line 451  rather than as numbers." Line 451  rather than as numbers."
451  (defun tramp-smb-handle-file-writable-p (filename)  (defun tramp-smb-handle-file-writable-p (filename)
452    "Like `file-writable-p' for tramp files."    "Like `file-writable-p' for tramp files."
453  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
454    (let  (user host path)    (let  (user host localname)
455      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
456        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
457      (save-excursion      (save-excursion
458        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
459               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
460               (entries (tramp-smb-get-file-entries user host share file))               (entries (tramp-smb-get-file-entries user host share file))
461               (entry (and entries               (entry (and entries
462                           (assoc (file-name-nondirectory file) entries))))                           (assoc (file-name-nondirectory file) entries))))
# Line 474  WILDCARD and FULL-DIRECTORY-P are not ha Line 474  WILDCARD and FULL-DIRECTORY-P are not ha
474      ;; this function is called with a non-directory ...      ;; this function is called with a non-directory ...
475      (setq filename (file-name-as-directory filename)))      (setq filename (file-name-as-directory filename)))
476  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
477    (let  (user host path)    (let  (user host localname)
478      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
479        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
480      (save-match-data      (save-match-data
481        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
482               (file (tramp-smb-get-path path nil))               (file (tramp-smb-get-localname localname nil))
483               (entries (tramp-smb-get-file-entries user host share file)))               (entries (tramp-smb-get-file-entries user host share file)))
484    
485          ;; Delete dummy "" entry, useless entries          ;; Delete dummy "" entry, useless entries
486          (setq entries          (setq entries
487                (if (file-directory-p filename)                (if (file-directory-p filename)
488                    (delq (assoc "" entries) entries)                    (delq (assoc "" entries) entries)
489                  ;; We just need the only and only entry FILENAME.                  ;; We just need the only and only entry FILENAME.
# Line 527  WILDCARD and FULL-DIRECTORY-P are not ha Line 527  WILDCARD and FULL-DIRECTORY-P are not ha
527    (unless (file-name-absolute-p dir)    (unless (file-name-absolute-p dir)
528      (setq dir (concat default-directory dir)))      (setq dir (concat default-directory dir)))
529  ;  (with-parsed-tramp-file-name dir nil  ;  (with-parsed-tramp-file-name dir nil
530    (let  (user host path)    (let  (user host localname)
531      (with-parsed-tramp-file-name dir l      (with-parsed-tramp-file-name dir l
532        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
533      (save-match-data      (save-match-data
534        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
535               (ldir (file-name-directory dir)))               (ldir (file-name-directory dir)))
536          ;; Make missing directory parts          ;; Make missing directory parts
537          (when (and parents share (not (file-directory-p ldir)))          (when (and parents share (not (file-directory-p ldir)))
# Line 548  WILDCARD and FULL-DIRECTORY-P are not ha Line 548  WILDCARD and FULL-DIRECTORY-P are not ha
548    (unless (file-name-absolute-p directory)    (unless (file-name-absolute-p directory)
549      (setq ldir (concat default-directory directory)))      (setq ldir (concat default-directory directory)))
550  ;  (with-parsed-tramp-file-name directory nil  ;  (with-parsed-tramp-file-name directory nil
551    (let  (user host path)    (let  (user host localname)
552      (with-parsed-tramp-file-name directory l      (with-parsed-tramp-file-name directory l
553        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
554      (save-match-data      (save-match-data
555        (let* ((share (tramp-smb-get-share path))        (let* ((share (tramp-smb-get-share localname))
556               (file (tramp-smb-get-path path nil)))               (file (tramp-smb-get-localname localname nil)))
557          (when (file-directory-p (file-name-directory directory))          (when (file-directory-p (file-name-directory directory))
558            (tramp-smb-maybe-open-connection user host share)            (tramp-smb-maybe-open-connection user host share)
559            (tramp-smb-send-command user host (format "mkdir \"%s\"" file)))            (tramp-smb-send-command user host (format "mkdir \"%s\"" file)))
# Line 581  WILDCARD and FULL-DIRECTORY-P are not ha Line 581  WILDCARD and FULL-DIRECTORY-P are not ha
581            (error "rename-file: file %s already exists" newname))            (error "rename-file: file %s already exists" newname))
582    
583  ;      (with-parsed-tramp-file-name newname nil  ;      (with-parsed-tramp-file-name newname nil
584        (let (user host path)        (let (user host localname)
585          (with-parsed-tramp-file-name newname l          (with-parsed-tramp-file-name newname l
586            (setq user l-user host l-host path l-path))            (setq user l-user host l-host localname l-localname))
587          (save-excursion          (save-excursion
588            (let ((share (tramp-smb-get-share path))            (let ((share (tramp-smb-get-share localname))
589                  (file (tramp-smb-get-path path t)))                  (file (tramp-smb-get-localname localname t)))
590              (tramp-smb-maybe-open-connection user host share)              (tramp-smb-maybe-open-connection user host share)
591              (tramp-message-for-buffer              (tramp-message-for-buffer
592               nil tramp-smb-method user host               nil tramp-smb-method user host
# Line 613  WILDCARD and FULL-DIRECTORY-P are not ha Line 613  WILDCARD and FULL-DIRECTORY-P are not ha
613                                filename))                                filename))
614        (error "File not overwritten")))        (error "File not overwritten")))
615  ;  (with-parsed-tramp-file-name filename nil  ;  (with-parsed-tramp-file-name filename nil
616    (let (user host path)    (let (user host localname)
617      (with-parsed-tramp-file-name filename l      (with-parsed-tramp-file-name filename l
618        (setq user l-user host l-host path l-path))        (setq user l-user host l-host localname l-localname))
619      (save-excursion      (save-excursion
620        (let ((share (tramp-smb-get-share path))        (let ((share (tramp-smb-get-share localname))
621              (file (tramp-smb-get-path path t))              (file (tramp-smb-get-localname localname t))
622              (curbuf (current-buffer))              (curbuf (current-buffer))
623              ;; We use this to save the value of `last-coding-system-used'              ;; We use this to save the value of `last-coding-system-used'
624              ;; after writing the tmp file.  At the end of the function,              ;; after writing the tmp file.  At the end of the function,
# Line 666  WILDCARD and FULL-DIRECTORY-P are not ha Line 666  WILDCARD and FULL-DIRECTORY-P are not ha
666    
667  ;; Internal file name functions  ;; Internal file name functions
668    
669  (defun tramp-smb-get-share (path)  (defun tramp-smb-get-share (localname)
670    "Returns the share name of PATH."    "Returns the share name of LOCALNAME."
671    (save-match-data    (save-match-data
672      (when (string-match "^/?\\([^/]+\\)/" path)      (when (string-match "^/?\\([^/]+\\)/" localname)
673        (match-string 1 path))))        (match-string 1 localname))))
674    
675  (defun tramp-smb-get-path (path convert)  (defun tramp-smb-get-localname (localname convert)
676    "Returns the file name of PATH.    "Returns the file name of LOCALNAME.
677  If CONVERT is non-nil exchange \"/\" by \"\\\\\"."  If CONVERT is non-nil exchange \"/\" by \"\\\\\"."
678    (save-match-data    (save-match-data
679      (let ((res path))      (let ((res localname))
680    
681        (setq        (setq
682         res (if (string-match "^/?[^/]+/\\(.*\\)" res)         res (if (string-match "^/?[^/]+/\\(.*\\)" res)
# Line 697  If CONVERT is non-nil exchange \"/\" by Line 697  If CONVERT is non-nil exchange \"/\" by
697    
698  ;; Share names of a host are cached. It is very unlikely that the  ;; Share names of a host are cached. It is very unlikely that the
699  ;; shares do change during connection.  ;; shares do change during connection.
700  (defun tramp-smb-get-file-entries (user host share path)  (defun tramp-smb-get-file-entries (user host share localname)
701    "Read entries which match PATH.    "Read entries which match LOCALNAME.
702  Either the shares are listed, or the `dir' command is executed.  Either the shares are listed, or the `dir' command is executed.
703  Only entries matching the path are returned.  Only entries matching the localname are returned.
704  Result is a list of (PATH MODE SIZE MONTH DAY TIME YEAR)."  Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
705    (save-excursion    (save-excursion
706      (save-match-data      (save-match-data
707        (let ((base (or (and (> (length path) 0)        (let ((base (or (and (> (length localname) 0)
708                             (string-match "\\([^/]+\\)$" path)                             (string-match "\\([^/]+\\)$" localname)
709                             (regexp-quote (match-string 1 path)))                             (regexp-quote (match-string 1 localname)))
710                        ""))                        ""))
711              res entry)              res entry)
712          (set-buffer (tramp-get-buffer nil tramp-smb-method user host))          (set-buffer (tramp-get-buffer nil tramp-smb-method user host))
# Line 719  Result is a list of (PATH MODE SIZE MONT Line 719  Result is a list of (PATH MODE SIZE MONT
719              (tramp-smb-send-command              (tramp-smb-send-command
720               user host               user host
721               (format "dir %s"               (format "dir %s"
722                       (if (zerop (length path)) "" (concat "\"" path "*\"")))))                       (if (zerop (length localname)) "" (concat "\"" localname "*\"")))))
723            (goto-char (point-min))            (goto-char (point-min))
724            ;; Loop the listing            ;; Loop the listing
725            (unless (re-search-forward tramp-smb-errors nil t)            (unless (re-search-forward tramp-smb-errors nil t)
# Line 780  Result is a list of (PATH MODE SIZE MONT Line 780  Result is a list of (PATH MODE SIZE MONT
780  (defun tramp-smb-read-file-entry (share)  (defun tramp-smb-read-file-entry (share)
781    "Parse entry in SMB output buffer.    "Parse entry in SMB output buffer.
782  If SHARE is result, entries are of type dir. Otherwise, shares are listed.  If SHARE is result, entries are of type dir. Otherwise, shares are listed.
783  Result is the list (PATH MODE SIZE MTIME)."  Result is the list (LOCALNAME MODE SIZE MTIME)."
784    (let ((line (buffer-substring (point) (tramp-point-at-eol)))    (let ((line (buffer-substring (point) (tramp-point-at-eol)))
785          path mode size month day hour min sec year mtime)          localname mode size month day hour min sec year mtime)
786    
787      (if (not share)      (if (not share)
788    
789          ; Read share entries          ; Read share entries
790          (when (string-match "^\\s-+\\(\\S-+\\)\\s-+Disk" line)          (when (string-match "^\\s-+\\(\\S-+\\)\\s-+Disk" line)
791            (setq path (match-string 1 line)            (setq localname (match-string 1 line)
792                  mode "dr-xr-xr-x"                  mode "dr-xr-xr-x"
793                  size 0))                  size 0))
794    
# Line 847  Result is the list (PATH MODE SIZE MTIME Line 847  Result is the list (PATH MODE SIZE MTIME
847               line (substring line 0 (- (1+ (length (match-string 2 line))))))               line (substring line 0 (- (1+ (length (match-string 2 line))))))
848            (return))            (return))
849    
850          ;; path          ;; localname
851          (if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-+$" line)          (if (string-match "^\\s-+\\(\\S-\\(.*\\S-\\)?\\)\\s-+$" line)
852              (setq path (match-string 1 line))              (setq localname (match-string 1 line))
853            (return))))            (return))))
854    
855      (when (and path mode size)      (when (and localname mode size)
856        (setq mtime        (setq mtime
857              (if (and sec min hour day month year)              (if (and sec min hour day month year)
858                  (encode-time                  (encode-time
# Line 860  Result is the list (PATH MODE SIZE MTIME Line 860  Result is the list (PATH MODE SIZE MTIME
860                   (cdr (assoc (downcase month) tramp-smb-parse-time-months))                   (cdr (assoc (downcase month) tramp-smb-parse-time-months))
861                   year)                   year)
862                '(0 0)))                '(0 0)))
863        (list path mode size mtime))))        (list localname mode size mtime))))
864    
865  ;; Inodes don't exist for SMB files.  Therefore we must generate virtual ones.  ;; Inodes don't exist for SMB files.  Therefore we must generate virtual ones.
866  ;; Used in `find-buffer-visiting'.  ;; Used in `find-buffer-visiting'.

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26