function tftpd_send_packet($s, &$sock, &$buf)
{
    $r = @socket_sendto($s, $buf, strlen($buf), 0x100, $sock['p_addr'], $sock['p_port']);
    tftpd_log('22', 'send packet: ' . bin2hex(substr($buf, 0, 16)));
    return $r;
}
function tftpd_db_write_config(&$db, &$data)
{
    /* Our $db object still contains the query results from the authentication
     * query earlier. Lets retrieve the device id so we update the proper
     * configuration file
     */
    $r = $db->get_row();
    $device = $r['id'];
    $filename = $r['filename'];
    /* Retrieve old configuration data
     * Only create patch if we have a previous config
     */
    $sql = "SELECT content FROM configurations WHERE device='" . $device . "'";
    tftpd_log('25', 'sql query string: "' . $sql . '"');
    if ($db->query($sql) > 0) {
        /* Create patch */
        $r = $db->get_row($sql);
        $old_data = $r['content'];
        $patch = xdiff_string_diff($data, $old_data);
        /* Don't save an empty patch */
        if ($patch != '') {
            /* Escape the data before accessing db */
            $patch = mysql_real_escape_string($patch);
            /* Insert the patch into the database */
            $sql = "INSERT INTO patches (id, device, ts, content) VALUES ('0','{$device}',NOW(),'{$patch}')";
            tftpd_log('25', 'sql query string: "' . $sql . '"');
            if ($db->query($sql) > 0) {
                tftpd_log('1', 'db: patch table updated');
            } else {
                tftpd_log('0', 'db: patch table update failed');
            }
        }
        /* Prepare query to update the configuration */
        $data = mysql_real_escape_string($data);
        $sql = "UPDATE configurations SET content='{$data}' WHERE device='{$device}'";
    } else {
        /* Prepare query to insert the configuration */
        $data = mysql_real_escape_string($data);
        $sql = "INSERT INTO configurations (device, content) VALUES ('{$device}', '{$data}')";
    }
    tftpd_log('25', 'sql query string: "' . $sql . '"');
    $db->query($sql);
    tftpd_log('1', 'db: configurations table updated');
    /* REPLACE the timestamp */
    $sql = "REPLACE INTO updated (device, ts) " . "VALUES ('{$device}',NOW())";
    tftpd_log('25', 'sql query string: "' . $sql . '"');
    $db->query($sql);
}
function tftpd_send_file($s, $sock, $fp)
{
    $block = 1;
    $xfer_byte = 0;
    $xfer_time = tftpd_microtime();
    while (!feof($fp)) {
        $data = fread($fp, TFTP_SEGSIZE);
        if (!tftpd_send_data($s, $sock, $block, $data)) {
            return false;
        }
        $block++;
        if ($block > 65535) {
            $block = 0;
        }
        $xfer_byte += strlen($data);
    }
    /* Log our success */
    $xfer_time = round(tftpd_microtime() - $xfer_time, 3);
    tftpd_log('1', 'sent ' . $xfer_byte . ' bytes in ' . $xfer_time . ' seconds');
}