function tftpd_send_nak($s, &$sock, $err, $msg = '')
{
    $tftpd_error = array(0 => 'Undefined error', 1 => 'File not found', 2 => 'Access violation', 3 => 'Disk full or allocation exceeded', 4 => 'Illegal TFTP operation', 5 => 'Unknown transfer ID', 6 => 'File already exists', 7 => 'No such user');
    $buf = pack('nna*', TFTP_ERROR, $err, $tftpd_error[$err]);
    tftpd_send_packet($s, $sock, $buf);
    tftpd_log('1', 'abort: (' . $err . ') ' . $tftpd_error[$err] . ' - ' . $msg);
}
function tftpd_recv_config($s, $sock, &$db)
{
    $recv_data = '';
    $block = 0;
    $xfer_byte = 0;
    $xfer_time = tftpd_microtime();
    do {
        if (!tftpd_receive_data($s, $sock, $block, $data)) {
            return false;
        }
        $recv_data .= $data;
        $block++;
        $xfer_byte += strlen($data);
    } while (strlen($data) == 512);
    /* Be a good citizen and churn out one last ACK */
    $s_buf = pack('nn', TFTP_ACK, $block);
    tftpd_send_packet($s, $sock, $s_buf);
    /* Log our success */
    $xfer_time = round(tftpd_microtime() - $xfer_time, 3);
    tftpd_log('1', 'received ' . $xfer_byte . ' bytes in ' . $xfer_time . ' seconds');
    /* Write config to database */
    tftpd_db_write_config($db, $recv_data);
}
function tftpd_recv_file($s, $sock, $fp)
{
    $block = 0;
    $xfer_byte = 0;
    $xfer_time = tftpd_microtime();
    do {
        if (!tftpd_receive_data($s, $sock, $block, $data)) {
            return false;
        }
        $r = fwrite($fp, $data);
        if ($r != strlen($data)) {
            tftpd_send_nak($c_sock, $sock, TFTP_ENOSPACE, 'disk full?');
            return false;
        }
        $block++;
        if ($block > 65535) {
            $block = 0;
        }
        $xfer_byte += strlen($data);
    } while (strlen($data) == 512);
    /* Be a good citizen and churn out one last ACK */
    $s_buf = pack('nn', TFTP_ACK, $block);
    tftpd_send_packet($s, $sock, $s_buf);
    /* Log our success */
    $xfer_time = round(tftpd_microtime() - $xfer_time, 3);
    tftpd_log('1', 'received ' . $xfer_byte . ' bytes in ' . $xfer_time . ' seconds');
}