bindzoneedit.vim 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. "
  2. " script downloaded from http://git.openics.org/cgit.cgi/bindzoneedit.vim/plain/bindzoneedit.vim
  3. "
  4. " File: bindzoneedit.vim
  5. " Description: Edit Bind zones safely
  6. " Author: Emmanuel Bouthenot <kolter@openics.org>
  7. " Version: 0.1
  8. " Last Modified: November 21, 2010
  9. " License: WTFPLv2 (see http://sam.zoy.org/wtfpl/)
  10. " Changelog:
  11. " 0.1: Initial Release
  12. if exists("loadedBindZoneEdit") || !executable('named-checkzone')
  13. finish
  14. endif
  15. let loadedBindZoneEdit = 1
  16. autocmd FileType bindzone execute('call BindZoneApply()')
  17. function BindZoneApply()
  18. autocmd BufWriteCmd <buffer> execute('call BindZoneChecker()')
  19. endfunction
  20. function BindUpdateSerial()
  21. let s:bufferLines = getbufline(bufnr("%"), 1, "$")
  22. let s:lineNumber = 0
  23. for s:line in s:bufferLines
  24. let s:lineNumber += 1
  25. let s:serial = matchlist(s:line, '^\(\s*\)\(2\d\{7\}\)\(\d\{2\}\)\(\s*;\s*Serial.*\)$')
  26. if s:serial != []
  27. if (strftime("%Y%m%d") == s:serial[2])
  28. let s:newserial = s:serial[2] . s:serial[3]+1
  29. else
  30. let s:newserial = strftime("%Y%m%d") . '01'
  31. endif
  32. call setline(s:lineNumber, s:serial[1] . s:newserial . s:serial[4])
  33. call cursor(s:lineNumber, strlen(s:serial[1] . s:newserial)+1)
  34. execute('highlight BindSerial ctermbg=red guibg=red ctermfg=white guifg=white')
  35. call matchadd("BindSerial", s:newserial)
  36. break
  37. endif
  38. endfor
  39. endfunction
  40. nmap <C-_> :call BindUpdateSerial()<CR>
  41. function BindZoneChecker()
  42. let s:currentFile = expand("%")
  43. let s:bufferContents = getbufline(bufnr("%"), 1, "$")
  44. let s:domain = matchlist(s:bufferContents, '^\$ORIGIN\s\+\(\S\+\)')
  45. if s:domain != []
  46. " If the file isn't writable don't do anything (as it could lock it up)
  47. if filewritable(s:currentFile)
  48. let s:zoneFile = tempname()
  49. exe writefile(s:bufferContents, s:zoneFile)
  50. " Check if the zone file got written (prevent disk space full)
  51. if filereadable(s:zoneFile)
  52. let s:output = system('named-checkzone ' . s:domain[1] . ' ' . s:zoneFile)
  53. let s:output = substitute(s:output, s:zoneFile, s:currentFile, 'g')
  54. call delete(s:zoneFile)
  55. " Check if the zone is correct
  56. let s:okMatch = matchstr(s:output, '\nOK\n')
  57. if s:okMatch != ''
  58. cclose
  59. " Avoids the annoying “Press ENTER to …” message
  60. if &modified
  61. call BindUpdateSerial()
  62. endif
  63. " Finally, we have to write the file
  64. noautocmd w
  65. " Avoids the annoying “Press ENTER to …” message
  66. redraw
  67. else
  68. let s:outputLines = split(s:output, "\n")
  69. let s:errorLines = []
  70. for s:line in s:outputLines
  71. let s:errorLine = matchlist(s:line, '^\(.\+\):\(\d\+\):\s\+\(.*\)$')
  72. if s:errorLine != []
  73. call add(s:errorLines, s:currentFile . ':' . s:errorLine[2] . ':' . s:errorLine[3])
  74. endif
  75. endfor
  76. " if it was impossible to detect errors properly, we still
  77. " had them to the error console in a “raw” way
  78. if s:errorLines == []
  79. for s:line in s:outputLines
  80. call add(s:errorLines, s:currentFile . ':0:' . s:line)
  81. endfor
  82. endif
  83. let s:cFile = tempname()
  84. exe writefile(s:errorLines, s:cFile)
  85. let s:errorWindowHeight = len(s:errorLines)+2
  86. " Limiting the error window rows
  87. if s:errorWindowHeight >= 15
  88. let s:errorWindowHeight = 15
  89. endif
  90. let s:oldCpoptions = &cpoptions
  91. let s:oldErrorFormat = &errorformat
  92. set cpoptions-=F
  93. set errorformat=%f:%l:%m
  94. execute('cfile ' . s:cFile)
  95. execute('botright cwindow ' . s:errorWindowHeight)
  96. call delete(s:cFile)
  97. let &cpoptions = s:oldCpoptions
  98. let &errorformat = s:oldErrorFormat
  99. redraw
  100. return
  101. endif
  102. endif
  103. endif
  104. endif
  105. if s:currentFile != ''
  106. endif
  107. endfunction