(local tftp (require :tftp))
(local { : realpath} (require :posix.stdlib))
(local { : view } (require :fennel))

(local options
       (match arg
         ["-a" ip-address dir]
         { :allow ip-address :base-directory (realpath dir)}

         [dir]
         { :allow nil :base-directory (realpath dir)}

         []
         (error "missing command line parameters")
         ))

(print (.. "TFTP serving from " options.base-directory))

(fn merge-pathname [directory filename]
  (if (directory:match "/$")
      (.. directory  filename)
      (.. directory "/" filename)))

(->
 (tftp:listen
  (fn [file host port]
    (if (or (not options.allow) (= host options.allow))
        (let [pathname (merge-pathname options.base-directory file)
              f (io.open pathname "rb")
              size (f:seek "end")]
          (f:seek "set" 0)
          (var eof? false)
          (values
           (fn handler [reqlen]
             (let [bytes (f:read reqlen)]
               (if bytes
                   (values true bytes)
                   (values false nil))))
           size))
        (error "host not allowed")))
  nil
  ["*"]
  69)

(os.exit))