func send_export_list(output *bufio.Writer, options uint32, globalSettings Settings) {
    if globalSettings.File != "" {
        _, file := filepath.Split(globalSettings.File)
        send_export_list_item(output, options, file)
        send_ack(output, options)
        return
    }
    var current_directory string
    var err error
    if globalSettings.Directory == "" {
        current_directory, err = os.Getwd()
        utils.ErrorCheck(err, true)
    }
    files, err := ioutil.ReadDir(current_directory + nbd_folder)
    utils.ErrorCheck(err, true)
    for _, file := range files {
        send_export_list_item(output, options, file.Name())
    }
    send_ack(output, options)
}
/*
First check for a specific file. If one is specified, use it. If not, check for a directory. If that is not
available, use the CWD.
package main
import (
    "fmt"
    "net"
    "../utils"
    "bufio"
    "encoding/binary"
    "os"
    "bytes"
    "io"
    "io/ioutil"
    "github.com/urfave/cli"
    "path/filepath"
    "strconv"
)
const nbd_folder = "/sample_disks/"
var characters_per_line = 100
var newline = 0
var line_number = 0
type Settings struct {
    ReadOnly    bool
    AutoFlush   bool
    Host        string
    Port        string
    Listen      string
    File        string
    Directory   string
    BufferLimit string
}
type Connection struct {
    File        string
    RemoteAddr  string
    ReadOnly    bool
}
var connections = make(map[string][]Connection)
func addConnection(filename string, readOnly bool, remoteAddr string) bool {
    currentConnections, ok := connections[filename]
    if ok == false {
        currentConnections = make([]Connection, 4)
    }
    if !readOnly {
        for _, conn := range currentConnections {
            if !conn.ReadOnly {
                fmt.Printf("Error, too many writable connections. %s is already connected to %s\n", remoteAddr, filename)
                return false
            }
        }
    }
    newConnection := Connection{
        File: filename,
        RemoteAddr: remoteAddr,
        ReadOnly: readOnly,
    }
    connections[filename] = append(currentConnections, newConnection)
    return true
}
var globalSettings Settings = Settings {
    ReadOnly: false,
    AutoFlush: true,
    Host: "localhost",
    Port: "8000",
    Listen: "",
    File: "",
    Directory: "sample_disks",
    BufferLimit: "2048",
}
func send_export_list_item(output *bufio.Writer, options uint32, export_name string) {
    data := make([]byte, 1024)
    length := len(export_name)
    offset := 0
    binary.BigEndian.PutUint32(data[offset:], uint32(length))   
    offset += 4
    copy(data[offset:], export_name)
    offset += length
    reply_type := uint32(2)      
    send_message(output, options, reply_type, uint32(offset), data)
}
func send_ack(output *bufio.Writer, options uint32) {
    send_message(output, options, utils.NBD_COMMAND_ACK, 0, nil)
}
func export_name(output *bufio.Writer, conn net.Conn, payload_size int, payload []byte, options uint32, globalSettings Settings) {
    fmt.Printf("have request to bind to: %s\n", string(payload[:payload_size]))
    defer conn.Close()
    var filename bytes.Buffer
    readOnly := false
    var current_directory = globalSettings.Directory
    var err error
    if current_directory == "" {
        current_directory, err = os.Getwd()
        utils.ErrorCheck(err, true)
    }
    filename.WriteString(current_directory)
    filename.WriteString(nbd_folder)
    filename.Write(payload[:payload_size])
    fmt.Printf("Opening file: %s\n", filename.String())
    fileMode := os.O_RDWR
    if globalSettings.ReadOnly || (options & utils.NBD_OPT_READ_ONLY != 0) {
        fmt.Printf("Read Only is set\n")
        fileMode = os.O_RDONLY
        readOnly = true
    }
    file, err := os.OpenFile(filename.String(), fileMode, 0644)
    utils.ErrorCheck(err, false)
    if err != nil {
        return
    }
    buffer := make([]byte, 256)
    offset := 0
    fs, err := file.Stat()
    file_size := uint64(fs.Size())
    binary.BigEndian.PutUint64(buffer[offset:], file_size)   
    offset += 8
    binary.BigEndian.PutUint16(buffer[offset:], 1)   
    offset += 2
    if (options & utils.NBD_FLAG_NO_ZEROES) != utils.NBD_FLAG_NO_ZEROES {
        offset += 124
    }
    _, err = output.Write(buffer[:offset])
    output.Flush()
    utils.ErrorCheck(err, false)
    if err != nil {
        return
    }
    buffer_limit, _ := strconv.Atoi(globalSettings.BufferLimit)
    buffer_limit *= 1024     
    buffer = make([]byte, buffer_limit)
    conn_reader := bufio.NewReader(conn)
    for {
        waiting_for := 28        
        _, err := io.ReadFull(conn_reader, buffer[:waiting_for])
        if err == io.EOF {
            fmt.Printf("Abort detected, escaping processing loop\n")
            break
        }
        utils.ErrorCheck(err, true)
        command := binary.BigEndian.Uint32(buffer[4:8])
        from := binary.BigEndian.Uint64(buffer[16:24])
        length := binary.BigEndian.Uint32(buffer[24:28])
        if int(length) > buffer_limit {
            fmt.Printf("E")
            file.Sync()
            return
        }
        newline += 1;
        if newline % characters_per_line == 0 {
            line_number++
            fmt.Printf("\n%5d: ", line_number * 100)
            newline -= characters_per_line
        }
        switch command {
        case utils.NBD_COMMAND_READ:
            fmt.Printf(".")
            _, err = file.ReadAt(buffer[16:16+length], int64(from))
            utils.ErrorCheck(err, true)
            binary.BigEndian.PutUint32(buffer[:4], utils.NBD_REPLY_MAGIC)
            binary.BigEndian.PutUint32(buffer[4:8], 0)                       
            conn.Write(buffer[:16+length])
            continue
        case utils.NBD_COMMAND_WRITE:
            if readOnly {
                fmt.Printf("E")
                fmt.Printf("\nAttempt to write to read only file blocked\n")
                continue
            }
            fmt.Printf("W")
            _, err := io.ReadFull(conn_reader, buffer[28:28+length])
            if err == io.EOF {
                fmt.Printf("Abort detected, escaping processing loop\n")
                break
            }
            utils.ErrorCheck(err, true)
            _, err = file.WriteAt(buffer[28:28+length], int64(from))
            utils.ErrorCheck(err, true)
            if globalSettings.AutoFlush {
                file.Sync()
            }
            binary.BigEndian.PutUint32(buffer[:4], utils.NBD_REPLY_MAGIC)
            binary.BigEndian.PutUint32(buffer[4:8], 0)                       
            conn.Write(buffer[:16])
            continue
        case utils.NBD_COMMAND_DISCONNECT:
            fmt.Printf("D")
            file.Sync()
            return
        }
    }
}