Node MySQL connection resultset having issue - mysql

Connected Node using MySQL (using mysql2/promise)
on
const sql = `
SELECT *
FROM Applicant
WHERE ApplicationId = ?
`;
const result = await this.mysqlManager.Query(sql,number);
console.log(result);
public async Query(sql: any, parameters?: any, connection?: PoolConnection): Promise<any>
{
const con = connection || (await this.GetConnection());
try
{
const data = await con.query(sql, parameters);
return data;
}
catch (error)
{
con.release();
throw error;
}
}
but got response
ColumnDefinition {
_buf: <Buffer 3a 00 00 16 03 64 65 66 08 70 72 6f 70 65 6c 6c 64 09 41 70 70 6c 69 63 61 6e 74 09 41 70 70 6c 69 63 61 6e 74 05 50 43
69 74 79 05 50 43 69 74 79 0c ... 2376 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 2329,
_schemaLength: 8,
_schemaStart: 2333,
_tableLength: 9,
_tableStart: 2342,
_orgTableLength: 9,
_orgTableStart: 2352,
_orgNameLength: 16,
_orgNameStart: 2379,
characterSet: 224,
encoding: 'utf8',
name: 'SalaryDayRangeTo',
columnLength: 80,
columnType: 253,
flags: 0,
decimals: 0
}
Can someone please help me with this issue?

const data = await con.query(sql, parameters); return data[0];
Since first element consist of data with other attributes consisting schema information.

Related

Decoding H264 Stream Always Returns MF_E_TRANSFORM_NEED_MORE_INPUT

I'm attempting to decode raw h264 from a network stream using the Media Foundation Transform CLSID_MSH264DecoderMFT. Setting up the transform seems to work and it's accepting data. However, no matter how much data I provide, it always returns MF_E_TRANSFORM_NEED_MORE_INPUT.
The document says, that the decoder will skip over all data until it finds valid Sequence and Picture Parameters. I'm providing this and then a raw data frame along with start codes:
1 00 00 00 01 67 42 c0 28 da 01 e0 19 fe 7c 05 a8 08 08 0a 00 00 03 00 02 00 00 03 00 61 1e 30 65
2 40 00 00 00 01 68 ce 3c 80 00 00 00 01 00 00 0e 6c 41 9a e0 eb 08 84 3c 14 ff fe 10 ff f8 64 14
3 f0 88 20 11 55 d5 7e 19 11 17 17 c5 c5 3f 05 00 a3 86 41 08 8a ae ab 58 8c 1f 11 88 cd f8 9f ff
4 f8 9d 78 21 f9 2a bf e2 3e 04 1f f8 20 08 92 7c 0e 33 52 67 e1 48 74 32 f8 5c 5f ca fd 77 12 df
5 3a 0f 93 11 89 2f 26 98 76 16 65 9b 78 87 77 ff ff fe 27 c6 fe b1 39 34 27 04 17 55 f0 61 fe 23
Above is only a partial sample, but it's representative of the data I provide to the transform.
Transform Setup:
ComPtr<IUnknown> pUnknown = nullptr;
HRESULT hResult = CoCreateInstance(CLSID_MSH264DecoderMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IUnknown, &pUnknown);
if (S_OK != hResult) {
LogError("Failed to create H264 decoder");
return false;
}
hResult = pUnknown->QueryInterface(IID_PPV_ARGS(&mVideoDecoder));
if (hResult != S_OK) {
LogError("Failed to create H264 decoder");
return false;
}
ComPtr<IMFMediaType> pInputMediaType = nullptr;
hResult = MFCreateMediaType(&pInputMediaType);
if (S_OK != hResult) {
return false;
}
pInputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
pInputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
std::shared_ptr<VideoMp4Track> videoTrack = mDemuxer->getVideoTrack();
uint32_t width = videoTrack->getWidth();
uint32_t height = videoTrack->getHeight();
MFSetAttributeSize(pInputMediaType.Get(), MF_MT_FRAME_SIZE, width, height);
MFSetAttributeRatio(pInputMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, width, height);
MFSetAttributeRatio(pInputMediaType.Get(), MF_MT_FRAME_RATE, videoTrack->getFrameRate(), 1);
pInputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_MixedInterlaceOrProgressive);
ComPtr<IMFAttributes> attributes;
mVideoDecoder->GetAttributes(&attributes);
hResult = attributes->SetUINT32(CODECAPI_AVLowLatencyMode, 1);
if (hResult != S_OK) {
LogError("Failed to set low latency mode. Video might be choppy.");
}
hResult = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, 1);
if (hResult != S_OK) {
LogError("Failed to set GPU acceleration. Video might be choppy.");
}
hResult = mVideoDecoder->SetInputType(0, pInputMediaType.Get(), 0);
if (hResult != S_OK) {
LogError("Failed to set input type for decoder");
return false;
}
ComPtr<IMFMediaType> pOutputType = nullptr;
hResult = MFCreateMediaType(&pOutputType);
if (S_OK != hResult) {
return false;
}
pOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
pOutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
MFSetAttributeSize(pOutputType.Get(), MF_MT_FRAME_SIZE, width, height);
MFSetAttributeRatio(pOutputType.Get(), MF_MT_PIXEL_ASPECT_RATIO, width, height);
MFSetAttributeRatio(pOutputType.Get(), MF_MT_FRAME_RATE, videoTrack->getFrameRate(), 1);
hResult = mVideoDecoder->SetOutputType(0, pOutputType.Get(), 0);
if (hResult != S_OK) {
LogError("Failed to set input type for decoder");
return false;
}
// Notify the resampler.
hResult = mVideoDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, NULL);
if (S_OK != hResult) {
LogError("Failed to send flush command to the decoder.");
return false;
}
hResult = mVideoDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL);
if (S_OK != hResult) {
LogError("Failed to send notify command to the decoder.");
return false;
}
hResult = mVideoDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL);
if (S_OK != hResult) {
LogError("Failed to send notify command to the decoder.");
return false;
}
I have no idea why it isn't able to decode, would appreciate any help.
Thanks.
Edit:
DataPtr transformData = MakeDataPtr();
uint32_t startCode = 0x01000000;
std::shared_ptr<VideoMp4Track> video = mImpl->mDemuxer->getVideoTrack();
transformData->appendBytes(&startCode, 4);
DataPtr sps = video->getSequenceParameters();
transformData->appendData(*sps);
transformData->appendBytes(&startCode, 4);
DataPtr pps = video->getPictureParameters();
transformData->appendData(*pps);
transformData->appendBytes(&startCode, 4);
transformData->appendData(*sampleData);
transformData->appendBytes(&startCode, 4);
ComPtr<IMFSample> pSample = mImpl->createMFSample(transformData->getBytes(), transformData->getSize());
if (nullptr == pSample) {
LogError("Failed to create the buffer for decoder input");
return nullptr;
}
HRESULT hResult = mImpl->mVideoDecoder->ProcessInput(0, pSample.Get(), 0);
if (hResult != S_OK) {
if (hResult == MF_E_NOTACCEPTING) {
mImpl->mVideoDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, NULL);
hResult = mImpl->mVideoDecoder->ProcessInput(0, pSample.Get(), 0);
}
else {
LogError("Error feeding to resampler...");
return nullptr;
}
}
DWORD dwStatus = 0;
// outputDataBuffer is empty, need to create it.
MFT_OUTPUT_DATA_BUFFER outputDataBuffer{};
ComPtr<IMFSample> pVideoSample = nullptr;
hResult = MFCreateSample(&pVideoSample);
if (S_OK != hResult) {
LogError("Failed to create a media sample for decoder output");
return false;
}
ComPtr<IMFMediaBuffer> pOutputBuffer = nullptr;
hResult = MFCreateMemoryBuffer(sampleData->getSize(), &pOutputBuffer);
if (S_OK != hResult) {
LogError("Failed to create a memory buffer for decoder output");
return false;
}
pVideoSample->AddBuffer(pOutputBuffer.Get());
outputDataBuffer.pSample = pVideoSample.Get();
do {
hResult = mImpl->mVideoDecoder->ProcessOutput(0, 1, &outputDataBuffer, &dwStatus);
if (hResult == MF_E_TRANSFORM_NEED_MORE_INPUT) {
// conversion end
break;
}
I've omitted the rest because it never gets further, it just stays in this loop populating the transform.
Edit 2:
(Not) Working sample on github
https://github.com/pma07pg/h264
The sample code was too large to dump here so I've put the main.cpp on github. Should be able to just put it into a VS project and run it off the bat.
There are few bugs in your code.
1.) You didn't account for the start code size
yours:
const uint32_t parameterInputSize = sizeof(pictureParameters) + sizeof(sequenceParameters);
mine:
const uint32_t parameterInputSize = sizeof(startCode) + sizeof(pictureParameters) + sizeof(startCode) + sizeof(sequenceParameters);
Your 'mdat's contain more than one AccessUnit. Each AccessUnit is prefixed with its length which you have to replace with a start code.
Your 'mdat':
'mdat' = <size> data[0] | <size> data[1] | ... | <size> data[n] |
Replace the size with a start code and break the multiple Access Units into individual Access Units.
Required decoder input:
00 00 00 01 data[0]
00 00 00 01 data[1]
...
00 00 00 01 data[n]
See details here: https://github.com/go4shoe/MedieFoundationExample

How to convert Buffer to base64 image in Node js

I am getting data from my SQL database like this:
const mysql = require("mysql");
const connection = mysql.createConnection({
host: "localhost",
user: "root",
database: "database",
password : ''
});
//connection.release();
connection.connect(function(err) {
if (err) console.log(err);
});
connection.query("SELECT image FROM table WHERE id=(SELECT max(id) FROM table);", function (err, result, fields) {
if (err) console.log(err);
console.log(result);
});
/*Output:
[
RowDataPacket {
image: <Buffer 64 61 74 61 3a 69 6d 61 67 65 2f 6f 63 74 65 74 2d 73 74 72 65 61 6d 3b 62 61 73 65 36 34 2c 69 56 42 4f 52 77 30 4b 47 67 6f 41 41 41 41 4e 53 55 68 ... 27941 more bytes>
}
]
*/
How can I convert result to a base64 image in Node.js? For Example:
'data:image/png;base64,iVBORw0KGgoAAAANS'
Since you’re receiving a Buffer back as output, Buffer.toString('base64') will convert the raw binary data in the buffer to a base64 representation of the data.
Buffer.toString() can also take other encodings, you can read more about the other supported encodings in the docs.
So for your above code you would use this to get your image as base64
const dataImagePrefix = `data:image/png;base64,`
const query = 'SELECT image FROM table WHERE id=(SELECT max(id) FROM table)'
connection.query(query, (err, result, fields) => {
if (err) {
console.log(err)
// Exit after handling error
return
}
// Return all results and for each result row
// convert to a base64 string with the dataImagePrefix prepended to each
return results.map(result => `${dataImagePrefix}${result.image.toString('base64')}`)
})
You can do it very simple,
const generateImageFromBuffer = buffer => {
let _buffer = new Buffer.from(buffer, 'base64');
return _buffer.toString('base64');
};

How can I insert a Buffer value to mysql database?

So I have the following code:
let sql = `INSERT INTO users(email, name, surname, stellarAccount, stellarSeed) VALUES(?, ?, ?, ?, ?)`;
let new_user = [
mysql.escape(args.email),
mysql.escape(args.name),
mysql.escape(args.surname),
mysql.escape(keypair.publicKey()),
mysql.escape(utils.encrypt(Buffer.from(keypair.secret(), "utf-8"))),
];
console.log(await utils.encrypt(Buffer.from(keypair.secret(), "utf-8")));
con.query(sql, new_user, (err, results, fields) => {
if (err) {
return console.error(err.message);
}
console.log(results);
});
The problem is that instead of the encrypted value in mysql I have only blank space. I tried to console log the following:
utils.encrypt(Buffer.from(keypair.secret(), "utf-8"))
and it looked something like this:
<Buffer 01 02 02 00 78 45 8c 88 86 55 00 4f 23 8e 1f 80 a8 1d 3d c4 b0 6a 4c de 3e 60 db 43 51 8d 12 26 56 f3 70 1a 7b 01 89 65 c5 ea 7b 91 ff 71 f6 46 a6 e7 ... 162 more bytes>
In mysql the table charset is utf8mb4 and utf8mb4_0900_ai and the column that is blank is BLOB, also I wanted to set Not Null the column at it's giving me an error, I can't set BLOB to be not null ?
How can I insert the encrypted value in mysql db correcly ?
It is not for a password, I need this value afterwards, but I was thinking that encrypting it in the db would be much better than inserting it there as a plain text.
You can convert your buffer to utf-8 string and then you can save it.
buf1.toString('utf8');
See working

How to display an image from mysql using Express

I have a sql table 'animals' where there are blobs images. I found out how to upload images but not how to display them.
I would like to display the image which is called 'Dog' in my table.
Here is my code, where I print the result of my blob img.
let sql = 'SELECT * FROM animals WHERE file_name=\'Dog\''
connection.query(sql, (err,result) => {
console.log(result[0].img)
})
Here is the result of my code:
<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 84 00 09 06 07 13 12 12 15 13 13 13 16 16 15 15 18 18 17 16 18 15 17 15 17 17 16 ... >
Is there is any way to display that picture?
Thank you.
You can use the Fetch API to get the resource on your web page.
You can display the image like this :
fetch('http://localhost:1234/your_api')
.then(function(response) {
return response.blob();
})
.then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
document.querySelector("#databaseimage").src = objectURL;
});
In HTML :
<img id="databaseimage"/>
You can read more about Fetch API here :
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

How can I implement server side SMTP STARTTLS?

I am trying to implement a simple SMTP server using Vala and GLib + GIO.
Plain text communication is no problem so far, but when it comes to TLS using STARTTLS things get harder.
This is the code I have so far:
const string appname = "vsmtpd";
const string hostname = "myserver";
const uint16 listenport = 10025;
const string keyfile = "vsmtpd.key";
const string certfile = "vsmtpd.crt";
// TODO: Parse EHLO instead of constant string
const string username = "myclient";
void process_request_plain (InputStream input, OutputStream output) throws Error {
output.write (#"220 $hostname ESMTP $appname\n".data);
var data_in = new DataInputStream (input);
string line;
while ((line = data_in.read_line (null)) != null) {
stdout.printf ("%s\n", line);
line = line.chomp ();
if (line.substring (0, 5) == "EHLO ") {
output.write (#"250-$hostname Hello $username\n".data);
output.write ("250 STARTTLS\n".data);
}
else if (line == "STARTTLS") {
output.write ("220 Go ahead\n".data);
break;
}
else {
output.write ("502 Command not implemented\n".data);
}
}
}
int main () {
try {
TlsCertificate cert = new TlsCertificate.from_files
(certfile, keyfile);
var service = new SocketService ();
service.add_inet_port (listenport, null);
service.start ();
while (true) {
SocketConnection conn = service.accept (null);
process_request_plain (conn.input_stream, conn.output_stream);
TlsServerConnection tlsconn = TlsServerConnection.#new (conn, cert);
assert_nonnull (tlsconn);
// TODO: Is this neccessary?
tlsconn.accept_certificate.connect ((peer_cert, errors) => {
stdout.printf ("TLS accepting peer cert\n");
return true;
});
try {
tlsconn.handshake ();
stdout.printf ("TLS handshake ok\n");
} catch (Error e) {
stdout.printf ("TLS handshake failed\n");
stderr.printf ("%s\n", e.message);
}
}
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
return 0;
}
Given a valid SSL certificate in vsmtpd.key and vsmtpd.crt (which I generated with openssl req -x509 -newkey rsa:2048 -keyout vsmtpd.key -out vsmtpd.pem -days 365 -nodes) I start the program and I also run this OpenSSL command to test STARTTLS:
openssl s_client -connect localhost:10025 -starttls smtp -debug
The output from my program is:
EHLO openssl.client.net
STARTTLS
TLS handshake failed
Stream is already closed
The output from OpenSSL is:
CONNECTED(00000003)
read from 0x6ae470 [0x6af050] (4096 bytes => 26 (0x1A))
0000 - 32 32 30 20 6d 79 73 65-72 76 65 72 20 45 53 4d 220 myserver ESM
0010 - 54 50 20 76 73 6d 74 70-64 0a TP vsmtpd.
write to 0x6ae470 [0x6b0060] (25 bytes => 25 (0x19))
0000 - 45 48 4c 4f 20 6f 70 65-6e 73 73 6c 2e 63 6c 69 EHLO openssl.cli
0010 - 65 6e 74 2e 6e 65 74 0d-0a ent.net..
read from 0x6ae470 [0x6af050] (4096 bytes => 28 (0x1C))
0000 - 32 35 30 2d 6d 79 73 65-72 76 65 72 20 48 65 6c 250-myserver Hel
0010 - 6c 6f 20 6d 79 63 6c 69-65 6e 74 0a lo myclient.
read from 0x6ae470 [0x6af050] (4096 bytes => 13 (0xD))
0000 - 32 35 30 20 53 54 41 52-54 54 4c 53 0a 250 STARTTLS.
write to 0x6ae470 [0x7ffdb4aea9e0] (10 bytes => 10 (0xA))
0000 - 53 54 41 52 54 54 4c 53-0d 0a STARTTLS..
read from 0x6ae470 [0x6a13a0] (8192 bytes => 13 (0xD))
0000 - 32 32 30 20 47 6f 20 61-68 65 61 64 0a 220 Go ahead.
write to 0x6ae470 [0x6aefa0] (204 bytes => 204 (0xCC))
0000 - 16 03 01 00 c7 01 00 00-c3 03 03 0e ac 05 35 45 ..............5E
0010 - db 95 f6 a7 37 55 d8 ca-14 d7 5f 8e 6a 62 08 50 ....7U...._.jb.P
0020 - c9 81 b7 55 75 a8 4c 17-c0 a1 53 00 00 76 00 a5 ...Uu.L...S..v..
0030 - 00 a3 00 a1 00 9f 00 6b-00 6a 00 69 00 68 00 39 .......k.j.i.h.9
0040 - 00 38 00 37 00 36 00 88-00 87 00 86 00 85 00 9d .8.7.6..........
0050 - 00 3d 00 35 00 84 00 a4-00 a2 00 a0 00 9e 00 67 .=.5...........g
0060 - 00 40 00 3f 00 3e 00 33-00 32 00 31 00 30 00 9a .#.?.>.3.2.1.0..
0070 - 00 99 00 98 00 97 00 45-00 44 00 43 00 42 00 9c .......E.D.C.B..
0080 - 00 3c 00 2f 00 96 00 41-00 07 00 05 00 04 00 16 .<./...A........
0090 - 00 13 00 10 00 0d 00 0a-00 15 00 12 00 0f 00 0c ................
00a0 - 00 09 00 ff 02 01 00 00-23 00 23 00 00 00 0d 00 ........#.#.....
00b0 - 16 00 14 06 01 06 02 05-01 05 02 04 01 04 02 03 ................
00c0 - 01 03 02 02 01 02 02 00-0f 00 01 01 ............
read from 0x6ae470 [0x6b4500] (7 bytes => -1 (0xFFFFFFFFFFFFFFFF))
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 80 bytes and written 239 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
What I understand from the output my program closes the connection before the TLS handshake can complete. (I also tried using Thunderbird and Claws Mail)
What am I doing wrong here?
PS: I couldn't find any example on how to use GTLsServerConnection in a STARTTLS situation.
Update:
I tried -ssl2, -ssl3, -tls1, -tls1_1, -tls1_2 options of OpenSSL which also don't work.
openssl s_client -connect localhost:10025 -starttls smtp -state
yields:
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:error in SSLv2/v3 read server hello A
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 100 bytes and written 239 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
So the client sends "client hello A", but the server doesn't send a correct "server hello A".
As an alternative you can also try gnutls-cli --crlf --starttls-proto=smtp --port 10025 localhost.
The output from GNUTLS_DEBUG_LEVEL=11 ./vsmtpd is:
gnutls[2]: Enabled GnuTLS logging...
gnutls[2]: Intel SSSE3 was detected
gnutls[2]: Intel AES accelerator was detected
gnutls[2]: Intel GCM accelerator was detected
gnutls[2]: Enabled GnuTLS logging...
gnutls[2]: Intel SSSE3 was detected
gnutls[2]: Intel AES accelerator was detected
gnutls[2]: Intel GCM accelerator was detected
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN RSA PRIVATE KEY'
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN DSA PRIVATE KEY'
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN EC PRIVATE KEY'
gnutls[3]: ASSERT: privkey.c:503
gnutls[2]: Falling back to PKCS #8 key decoding
EHLO openssl.client.net
STARTTLS
gnutls[5]: REC[0xfa67e0]: Allocating epoch #0
gnutls[3]: ASSERT: gnutls_constate.c:586
gnutls[5]: REC[0xfa67e0]: Allocating epoch #1
gnutls[3]: ASSERT: gnutls_buffers.c:1138
gnutls[10]: READ: -1 returned from 0xfa4120, errno=0 gerrno=5
gnutls[3]: ASSERT: gnutls_buffers.c:364
gnutls[3]: ASSERT: gnutls_buffers.c:572
gnutls[3]: ASSERT: gnutls_record.c:1058
gnutls[3]: ASSERT: gnutls_record.c:1179
gnutls[3]: ASSERT: gnutls_buffers.c:1392
gnutls[3]: ASSERT: gnutls_handshake.c:1428
gnutls[3]: ASSERT: gnutls_handshake.c:3098
gnutls[3]: ASSERT: gnutls_db.c:334
TLS handshake failed
Stream is already closed
gnutls[5]: REC[0xfa67e0]: Start of epoch cleanup
gnutls[5]: REC[0xfa67e0]: End of epoch cleanup
gnutls[5]: REC[0xfa67e0]: Epoch #0 freed
gnutls[5]: REC[0xfa67e0]: Epoch #1 freed
The problem is hidden somewhere in the implementation of DataInputStream.
Once I removed it and used the following replacement for read_line () instead, it works just fine.
string? read_line (InputStream input) throws Error {
var buffer = new uint8[1];
var sb = new StringBuilder ();
buffer[0] = '\0';
while (buffer[0] != '\n') {
input.read (buffer);
sb.append_c ((char) buffer[0]);
}
return (string) sb.data;
}
void process_request_plain (InputStream input, OutputStream output) throws Error {
output.write (#"220 $hostname ESMTP $appname\n".data);
string line;
while ((line = read_line (input)) != null) {
stdout.printf ("%s\n", line);
line = line.chomp ();
if (line.substring (0, 5) == "EHLO ") {
output.write (#"250-$hostname Hello $username\n".data);
output.write ("250 STARTTLS\n".data);
}
else if (line == "STARTTLS") {
output.write ("220 Go ahead\n".data);
break;
}
else {
output.write ("502 Command not implemented\n".data);
}
}
}