Loading ...
Sorry, an error occurred while loading the content.

Re: Vim mutilating file permissions through Samba?

Expand Messages
  • John
    I said I d post my results on this issue just in case it ever hits anyone else - below is the code I ve settled on which is working well for my particular
    Message 1 of 14 , Oct 7, 2010
    • 0 Attachment
      I said I'd post my results on this issue just in case it ever hits
      anyone else - below is the code I've settled on which is working well
      for my particular needs. (And note - my ssh mechanism is not always
      reliable so I try to only use it when I believe I need to.)

      John

      let s:linuxServer = 'devel'
      let s:linuxServerMappings = { 'j': '/home/john' }

      function! GetFilePermissions(...) " {{{3
      " Function to get a file's permissions.
      " With no arg, assumes current buffer, and returns a cached result
      unless v:cmdbang is set
      if a:0 == 0
      " Use the current buffer. First, check if the cached version is
      appropriate
      if exists('b:SavedFilePermissions')
      \ && b:SavedFilePermissions =~ '^\d\{3,4\}$'
      \ && v:cmdbang != 1
      return b:SavedFilePermissions
      else
      let file = expand('%:p')
      endif
      else
      let file = expand(a:1)
      endif

      let cmd = ''
      if exists('s:linuxServerMappings') && file =~
      '\c^['.join(keys(s:linuxServerMappings),'').']:'
      " File on linux fileserver - try remotely on linuxServer
      let f = file
      for drive in keys(s:linuxServerMappings)
      exec 'let f = substitute(f, ''\c^\('.drive.'\):'',
      '''.s:linuxServerMappings[drive].''', ''g'')'
      endfor
      let f = substitute(f, '\\', '\/', 'g')
      let cmd .= 'ssh -x '.s:linuxServer.' '
      else
      " Local file - try locally, converting any Win paths to Cygwin
      first
      let f = ConvertPathWinToCyg(file)
      endif
      let cmd .= 'stat -c"%a" "'.f.'"'
      let perms = Chomp(system(cmd))
      if v:shell_error != 0 || perms !~ '^\d\{3,4\}$'
      echom file.": unable to get permissions with command '".cmd."'"
      let perms = 'unobtainable'
      endif
      if a:0 == 0
      let b:SavedFilePermissions = perms
      endif
      return perms
      endfunction

      function! SetFilePermissions(...) " {{{3
      " Function to set a file's permissions
      " With no args, assumes current buffer, uses cached permissions.
      " With one arg, it must be the permissions to set on the current
      buffer
      " With two args, it must be the permissions to set and the file to
      set them on
      if a:0 == 0
      let file = expand('%:p')
      if !exists('b:SavedFilePermissions')
      echom "SetFilePermissions() unable to set permissions on
      ".file." since b:SavedFilePermissions not set"
      return
      else
      let perms = b:SavedFilePermissions
      endif
      elseif a:0 == 1
      let file = expand('%:p')
      let perms = a:1
      elseif a:0 == 2
      let perms = a:1
      let file = a:2
      endif

      if perms !~ '^\d\{3,4\}$'
      echom "SetFilePermissions(...) : perms=".perms.",file=".file."
      doing nothing due to invalid permissions"
      return
      endif

      let cmd = ''
      if exists('s:linuxServerMappings') && file =~
      '\c^['.join(keys(s:linuxServerMappings),'').']:'
      " File on linux fileserver - try remotely on linuxServer
      let f = file
      for drive in keys(s:linuxServerMappings)
      exec 'let f = substitute(f, ''\c^\('.drive.'\):'',
      '''.s:linuxServerMappings[drive].''', ''g'')'
      endfor
      let f = substitute(f, '\\', '\/', 'g')
      let cmd .= 'ssh -x -vvv '.s:linuxServer.' '
      else
      " Local file - try locally, converting any Win paths to Cygwin
      first
      let f = ConvertPathWinToCyg(file)
      endif
      let cmd .= 'chmod '.perms.' "'.f.'"'
      let output = system(cmd)
      if v:shell_error != 0
      echom "SetFilePermissions(...) : perms=".perms.",file=".file."
      unable to set permissions with command '".cmd."', debug saved in @z"
      let @z = output
      return
      endif
      endfunction

      function! SetFilePermissionsIfRequired() " {{{3
      " Function to call SetFilePermissions, but only if it's necessary
      for my particular circumstances
      " My specific issues are
      " 1. 'ux' permissions on linux server files not being preserved
      " 2. 'ux' permissions being given to local files (on windows)
      inappropriately
      if !exists('b:SavedFilePermissions')
      return
      endif

      let user_permission_digit = strpart(b:SavedFilePermissions,
      strlen(b:SavedFilePermissions)-3, 1)
      if (exists('s:linuxServerMappings') && ((expand('%:p') =~
      '\c^['.join(keys(s:linuxServerMappings),'').']:' &&
      user_permission_digit % 2 == 1)
      \ || expand('%:p') !~
      '\c^['.join(keys(s:linuxServerMappings),'').']:'))
      \ || (!exists('s:linuxServerMappings') && user_permission_digit %
      2 == 0)
      call SetFilePermissions()
      endif
      endfunction

      function! ConvertPathWinToCyg(path) "{{{3
      let path = a:path
      if path =~ '^.:' || path =~ '\\'
      let path = Chomp(system('cygpath "'.a:path.'"'))
      if v:shell_error != 0
      echoe "ConvertPathWinToCyg(".a:path."): cygpath command failed -
      cygwin not installed or not in path?"
      let path = "ConvertPathWinToCygFailedToConvertPath"
      endif
      endif
      return path
      endfunction

      function! Chomp(line) " {{{3 Perl's chomp function
      return substitute(a:line, '\v(\r)?(\n)?$', '', '')
      endfunction

      autocmd BufWritePre * call GetFilePermissions()
      autocmd BufWritePost * call SetFilePermissionsIfRequired()

      --
      You received this message from the "vim_use" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php
    Your message has been successfully submitted and would be delivered to recipients shortly.