Beispiel #1
0
nsresult
nsNDNChannel::BeginPumpingData() {
  nsresult rv;
  nsCOMPtr<nsIInputStream> stream;
  nsCOMPtr<nsIChannel> channel;

  rv = OpenContentStream(true, getter_AddRefs(stream),
                         getter_AddRefs(channel));

  if (NS_FAILED(rv))
    return rv;

  NS_ASSERTION(!stream || !channel, "Got both a channel and a stream?");

  /*
  if (channel) {
      rv = NS_DispatchToCurrentThread(new RedirectRunnable(this, channel));
      if (NS_SUCCEEDED(rv))
          mWaitingOnAsyncRedirect = true;
      return rv;
  }
  */

  rv = NS_NewInputStreamPump(getter_AddRefs(mPump), stream, -1, -1, 0, 0,
                                 true);
  if (NS_SUCCEEDED(rv))
    rv = mPump->AsyncRead(this, nsnull);

  return rv;
}
Beispiel #2
0
nsresult
nsWyciwygChannel::ReadFromCache()
{
    LOG(("nsWyciwygChannel::ReadFromCache [this=%p] ", this));

    NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE);
    nsresult rv;

    // Get the stored security info
    mCacheEntry->GetSecurityInfo(getter_AddRefs(mSecurityInfo));

    nsAutoCString tmpStr;
    rv = mCacheEntry->GetMetaDataElement("inhibit-persistent-caching",
                                         getter_Copies(tmpStr));
    if (NS_SUCCEEDED(rv) && tmpStr.EqualsLiteral("1"))
        mLoadFlags |= INHIBIT_PERSISTENT_CACHING;

    // Get a transport to the cached data...
    rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
    if (NS_FAILED(rv))
        return rv;
    NS_ENSURE_TRUE(mCacheInputStream, NS_ERROR_UNEXPECTED);

    rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mCacheInputStream);
    if (NS_FAILED(rv)) return rv;

    // Pump the cache data downstream
    return mPump->AsyncRead(this, nullptr);
}
Beispiel #3
0
inline nsresult nsZipWriter::BeginProcessingRemoval(int32_t aPos)
{
    // Open the zip file for reading
    nsCOMPtr<nsIInputStream> inputStream;
    nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream),
                                             mFile);
    NS_ENSURE_SUCCESS(rv, rv);
    nsCOMPtr<nsIInputStreamPump> pump;
    rv = NS_NewInputStreamPump(getter_AddRefs(pump), inputStream, -1, -1, 0,
                               0, true);
    if (NS_FAILED(rv)) {
        inputStream->Close();
        return rv;
    }
    nsCOMPtr<nsIStreamListener> listener;
    rv = NS_NewSimpleStreamListener(getter_AddRefs(listener), mStream, this);
    if (NS_FAILED(rv)) {
        inputStream->Close();
        return rv;
    }

    nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mStream);
    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
                        mHeaders[aPos]->mOffset);
    if (NS_FAILED(rv)) {
        inputStream->Close();
        return rv;
    }

    uint32_t shift = (mHeaders[aPos + 1]->mOffset -
                      mHeaders[aPos]->mOffset);
    mCDSOffset -= shift;
    int32_t pos2 = aPos + 1;
    while (pos2 < mHeaders.Count()) {
        mEntryHash.Put(mHeaders[pos2]->mName, pos2 - 1);
        mHeaders[pos2]->mOffset -= shift;
        pos2++;
    }

    mEntryHash.Remove(mHeaders[aPos]->mName);
    mHeaders.RemoveObjectAt(aPos);
    mCDSDirty = true;

    rv = pump->AsyncRead(listener, nullptr);
    if (NS_FAILED(rv)) {
        inputStream->Close();
        Cleanup();
        return rv;
    }
    return NS_OK;
}
Beispiel #4
0
NS_IMETHODIMP
nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
{
    LOG(("nsJARChannel::AsyncOpen [this=%x]\n", this));

    NS_ENSURE_ARG_POINTER(listener);
    NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);

    mJarFile = nsnull;
    mIsUnsafe = PR_TRUE;

    // Initialize mProgressSink
    NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);

    nsresult rv = EnsureJarInput(PR_FALSE);
    if (NS_FAILED(rv)) return rv;

    // These variables must only be set if we're going to trigger an
    // OnStartRequest, either from AsyncRead or OnDownloadComplete.
    mListener = listener;
    mListenerContext = ctx;
    mIsPending = PR_TRUE;
    if (mJarInput) {
        // create input stream pump and call AsyncRead as a block
        rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mJarInput);
        if (NS_SUCCEEDED(rv))
            rv = mPump->AsyncRead(this, nsnull);

        // If we failed to create the pump or initiate the AsyncRead,
        // then we need to clear these variables.
        if (NS_FAILED(rv)) {
            mIsPending = PR_FALSE;
            mListenerContext = nsnull;
            mListener = nsnull;
            return rv;
        }
    }

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nsnull);

    return NS_OK;
}
Beispiel #5
0
/**
 * asynchronously copy file.
 */
static nsresult
RunTest(nsIFile *file, int64_t offset, int64_t length)
{
    nsresult rv;

    LOG(("RunTest\n"));

    nsCOMPtr<nsIInputStream> stream;
    rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsIInputStreamPump> pump;
    rv = NS_NewInputStreamPump(getter_AddRefs(pump), stream, offset, length);
    if (NS_FAILED(rv)) return rv;

    rv = pump->AsyncRead(new MyListener(), nullptr);
    if (NS_FAILED(rv)) return rv;

    PumpEvents();
    return NS_OK;
}
Beispiel #6
0
nsresult
nsWyciwygChannel::ReadFromCache()
{
    LOG(("nsWyciwygChannel::ReadFromCache [this=%x] ", this));

    NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE);
    nsresult rv;

    // Get the stored security info
    mCacheEntry->GetSecurityInfo(getter_AddRefs(mSecurityInfo));

    // Get a transport to the cached data...
    rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(mCacheInputStream));
    if (NS_FAILED(rv))
        return rv;
    NS_ENSURE_TRUE(mCacheInputStream, NS_ERROR_UNEXPECTED);

    rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mCacheInputStream);
    if (NS_FAILED(rv)) return rv;

    // Pump the cache data downstream
    return mPump->AsyncRead(this, nsnull);
}
Beispiel #7
0
NS_IMETHODIMP
nsJARChannel::OnDownloadComplete(nsIDownloader *downloader,
                                 nsIRequest    *request,
                                 nsISupports   *context,
                                 nsresult       status,
                                 nsIFile       *file)
{
    nsresult rv;

    nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
    if (channel) {
        PRUint32 loadFlags;
        channel->GetLoadFlags(&loadFlags);
        if (loadFlags & LOAD_REPLACE) {
            mLoadFlags |= LOAD_REPLACE;

            if (!mOriginalURI) {
                SetOriginalURI(mJarURI);
            }

            nsCOMPtr<nsIURI> innerURI;
            rv = channel->GetURI(getter_AddRefs(innerURI));
            if (NS_SUCCEEDED(rv)) {
                nsCOMPtr<nsIJARURI> newURI;
                rv = mJarURI->CloneWithJARFile(innerURI,
                                               getter_AddRefs(newURI));
                if (NS_SUCCEEDED(rv)) {
                    mJarURI = newURI;
                }
            }
            if (NS_SUCCEEDED(status)) {
                status = rv;
            }
        }
    }

    if (NS_SUCCEEDED(status) && channel) {
        // Grab the security info from our base channel
        channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));

        nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
        if (httpChannel) {
            // We only want to run scripts if the server really intended to
            // send us a JAR file.  Check the server-supplied content type for
            // a JAR type.
            nsCAutoString header;
            httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"),
                                           header);
            nsCAutoString contentType;
            nsCAutoString charset;
            NS_ParseContentType(header, contentType, charset);
            nsCAutoString channelContentType;
            channel->GetContentType(channelContentType);
            mIsUnsafe = !(contentType.Equals(channelContentType) &&
                          (contentType.EqualsLiteral("application/java-archive") ||
                           contentType.EqualsLiteral("application/x-jar")));
        } else {
            nsCOMPtr<nsIJARChannel> innerJARChannel(do_QueryInterface(channel));
            if (innerJARChannel) {
                PRBool unsafe;
                innerJARChannel->GetIsUnsafe(&unsafe);
                mIsUnsafe = unsafe;
            }
        }

        channel->GetContentDisposition(mContentDisposition);
    }

    if (NS_SUCCEEDED(status) && mIsUnsafe) {
        PRBool allowUnpack = PR_FALSE;

        nsCOMPtr<nsIPrefBranch> prefs =
            do_GetService(NS_PREFSERVICE_CONTRACTID);
        if (prefs) {
            prefs->GetBoolPref("network.jar.open-unsafe-types", &allowUnpack);
        }

        if (!allowUnpack) {
            status = NS_ERROR_UNSAFE_CONTENT_TYPE;
        }
    }

    if (NS_SUCCEEDED(status)) {
        // Refuse to unpack view-source: jars even if open-unsafe-types is set.
        nsCOMPtr<nsIViewSourceChannel> viewSource = do_QueryInterface(channel);
        if (viewSource) {
            status = NS_ERROR_UNSAFE_CONTENT_TYPE;
        }
    }

    if (NS_SUCCEEDED(status)) {
        mJarFile = file;
    
        rv = CreateJarInput(nsnull);
        if (NS_SUCCEEDED(rv)) {
            // create input stream pump
            rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mJarInput);
            if (NS_SUCCEEDED(rv))
                rv = mPump->AsyncRead(this, nsnull);
        }
        status = rv;
    }

    if (NS_FAILED(status)) {
        mStatus = status;
        OnStartRequest(nsnull, nsnull);
        OnStopRequest(nsnull, nsnull, status);
    }

    return NS_OK;
}
Beispiel #8
0
NS_IMETHODIMP
nsGopherChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
    PR_LOG(gGopherLog, PR_LOG_DEBUG, ("nsGopherChannel::AsyncOpen() called [this=%x]\n",
                                      this));

    // get callback interfaces...

    nsresult rv;

    PRInt32 port;
    rv = mUrl->GetPort(&port);
    if (NS_FAILED(rv))
        return rv;
 
    rv = NS_CheckPortSafety(port, "gopher");
    if (NS_FAILED(rv))
        return rv;

    // push stream converters in front of the consumer...
    nsCOMPtr<nsIStreamListener> converter;
    rv = PushStreamConverters(aListener, getter_AddRefs(converter));
    if (NS_FAILED(rv)) return rv;
    
    // create socket transport
    nsCOMPtr<nsISocketTransportService> socketService = 
             do_GetService(kSocketTransportServiceCID, &rv);
    if (NS_FAILED(rv)) return rv;

    rv = socketService->CreateTransport(nsnull, 0,
                                        mHost,
                                        mPort,
                                        mProxyInfo,
                                        getter_AddRefs(mTransport));
    if (NS_FAILED(rv)) return rv;

    // setup notification callbacks...
    if (!(mLoadFlags & LOAD_BACKGROUND)) {
        nsCOMPtr<nsIEventQueue> eventQ;
        NS_GetCurrentEventQ(getter_AddRefs(eventQ));
        if (eventQ)
            mTransport->SetEventSink(this, eventQ);
    }

    // open buffered, asynchronous socket input stream, and use a input stream
    // pump to read from it.
    nsCOMPtr<nsIInputStream> input;
    rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(input));
    if (NS_FAILED(rv)) return rv;

    rv = SendRequest();
    if (NS_FAILED(rv)) return rv;

    rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input);
    if (NS_FAILED(rv)) return rv;

    rv = mPump->AsyncRead(this, nsnull);
    if (NS_FAILED(rv)) return rv;

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nsnull);

    mIsPending = PR_TRUE;
    if (converter)
        mListener = converter;
    else
        mListener = aListener;
    mListenerContext = ctxt;
    return NS_OK;
}
NS_IMETHODIMP
nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
    nsresult rv = NS_CheckPortSafety(mPort, "finger");
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
    NS_ENSURE_STATE(thread);

    //
    // create transport
    //
    nsCOMPtr<nsISocketTransportService> sts = 
             do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;

    rv = sts->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo,
                              getter_AddRefs(mTransport));
    if (NS_FAILED(rv)) return rv;

    // not fatal if this fails
    mTransport->SetEventSink(this, thread);

    rv = WriteRequest(mTransport);
    if (NS_FAILED(rv)) return rv;

    //
    // create TXT to HTML stream converter
    //
    nsCOMPtr<nsIStreamConverterService> scs = 
             do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsIStreamListener> convListener;
    rv = scs->AsyncConvertData("text/plain", "text/html", this, nsnull,
                               getter_AddRefs(convListener));
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsITXTToHTMLConv> conv = do_QueryInterface(convListener);
    if (conv) {
        nsCAutoString userHost;
        rv = mURI->GetPath(userHost);

        nsAutoString title;
        title.AppendLiteral("Finger information for ");
        AppendUTF8toUTF16(userHost, title);

        conv->SetTitle(title.get());
        conv->PreFormatHTML(PR_TRUE);
    }

    //
    // open input stream, and create input stream pump...
    //
    nsCOMPtr<nsIInputStream> sockIn;
    rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(sockIn));
    if (NS_FAILED(rv)) return rv;

    rv = NS_NewInputStreamPump(getter_AddRefs(mPump), sockIn);
    if (NS_FAILED(rv)) return rv;

    rv = mPump->AsyncRead(convListener, nsnull);
    if (NS_FAILED(rv)) return rv;

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nsnull);

    mListener = aListener;
    mListenerContext = ctxt;
    return NS_OK;
}
Beispiel #10
0
inline nsresult nsZipWriter::BeginProcessingAddition(nsZipQueueItem* aItem,
                                                     bool* complete)
{
    if (aItem->mFile) {
        bool exists;
        nsresult rv = aItem->mFile->Exists(&exists);
        NS_ENSURE_SUCCESS(rv, rv);

        if (!exists) return NS_ERROR_FILE_NOT_FOUND;

        bool isdir;
        rv = aItem->mFile->IsDirectory(&isdir);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = aItem->mFile->GetLastModifiedTime(&aItem->mModTime);
        NS_ENSURE_SUCCESS(rv, rv);
        aItem->mModTime *= PR_USEC_PER_MSEC;

        rv = aItem->mFile->GetPermissions(&aItem->mPermissions);
        NS_ENSURE_SUCCESS(rv, rv);

        if (!isdir) {
            // Set up for fall through to stream reader
            rv = NS_NewLocalFileInputStream(getter_AddRefs(aItem->mStream),
                                            aItem->mFile);
            NS_ENSURE_SUCCESS(rv, rv);
        }
        // If a dir then this will fall through to the plain dir addition
    }

    uint32_t zipAttributes = ZIP_ATTRS(aItem->mPermissions, ZIP_ATTRS_FILE);

    if (aItem->mStream || aItem->mChannel) {
        nsRefPtr<nsZipHeader> header = new nsZipHeader();
        NS_ENSURE_TRUE(header, NS_ERROR_OUT_OF_MEMORY);

        header->Init(aItem->mZipEntry, aItem->mModTime, zipAttributes,
                     mCDSOffset);
        nsresult rv = header->WriteFileHeader(mStream);
        NS_ENSURE_SUCCESS(rv, rv);

        nsRefPtr<nsZipDataStream> stream = new nsZipDataStream();
        NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY);
        rv = stream->Init(this, mStream, header, aItem->mCompression);
        NS_ENSURE_SUCCESS(rv, rv);

        if (aItem->mStream) {
            nsCOMPtr<nsIInputStreamPump> pump;
            rv = NS_NewInputStreamPump(getter_AddRefs(pump), aItem->mStream,
                                       -1, -1, 0, 0, true);
            NS_ENSURE_SUCCESS(rv, rv);

            rv = pump->AsyncRead(stream, nullptr);
            NS_ENSURE_SUCCESS(rv, rv);
        }
        else {
            rv = aItem->mChannel->AsyncOpen(stream, nullptr);
            NS_ENSURE_SUCCESS(rv, rv);
        }

        return NS_OK;
    }

    // Must be plain directory addition
    *complete = true;
    return InternalAddEntryDirectory(aItem->mZipEntry, aItem->mModTime,
                                     aItem->mPermissions);
}
// stop binding is a "notification" informing us that the stream associated with aURL is going away. 
NS_IMETHODIMP nsMailboxProtocol::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult aStatus)
{
  nsresult rv;
  if (m_nextState == MAILBOX_READ_FOLDER && m_mailboxParser)
  {
    // we need to inform our mailbox parser that there is no more incoming data...
    m_mailboxParser->OnStopRequest(request, ctxt, aStatus);
  }
  else if (m_nextState == MAILBOX_READ_MESSAGE) 
  {
    DoneReadingMessage();
  }
  // I'm not getting cancel status - maybe the load group still has the status.
  PRBool stopped = PR_FALSE;
  if (m_runningUrl)
  {
    nsCOMPtr <nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
    if (mailnewsUrl)
    {
      nsCOMPtr <nsIMsgWindow> window;
      mailnewsUrl->GetMsgWindow(getter_AddRefs(window));
      if (window)
        window->GetStopped(&stopped);
    }
    
    if (!stopped && NS_SUCCEEDED(aStatus) && (m_mailboxAction == nsIMailboxUrl::ActionCopyMessage || m_mailboxAction == nsIMailboxUrl::ActionMoveMessage))
    {
      PRUint32 numMoveCopyMsgs;
      PRUint32 curMoveCopyMsgIndex;
      rv = m_runningUrl->GetNumMoveCopyMsgs(&numMoveCopyMsgs);
      if (NS_SUCCEEDED(rv) && numMoveCopyMsgs > 0)
      {
        m_runningUrl->GetCurMoveCopyMsgIndex(&curMoveCopyMsgIndex);
        if (++curMoveCopyMsgIndex < numMoveCopyMsgs)
        {
          if (!mSuppressListenerNotifications && m_channelListener)
          {
            nsCOMPtr<nsICopyMessageStreamListener> listener = do_QueryInterface(m_channelListener, &rv);
            if (listener)
            {
              listener->EndCopy(ctxt, aStatus);
              listener->StartMessage(); // start next message.
            }
          }
          m_runningUrl->SetCurMoveCopyMsgIndex(curMoveCopyMsgIndex);
          nsCOMPtr <nsIMsgDBHdr> nextMsg;
          rv = m_runningUrl->GetMoveCopyMsgHdrForIndex(curMoveCopyMsgIndex, getter_AddRefs(nextMsg));
          if (NS_SUCCEEDED(rv) && nextMsg)
          {
            PRUint32 msgSize = 0;
            nsMsgKey msgKey;
            nsCOMPtr <nsIMsgFolder> msgFolder;
            nextMsg->GetFolder(getter_AddRefs(msgFolder));
            NS_ASSERTION(msgFolder, "couldn't get folder for next msg in multiple msg local copy");
            if (msgFolder)
            {
              nsCString uri;
              msgFolder->GetUriForMsg(nextMsg, uri);
              nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(m_runningUrl);
              if (msgUrl)
              {
                msgUrl->SetOriginalSpec(uri.get());
                msgUrl->SetUri(uri.get());
                
                nextMsg->GetMessageKey(&msgKey);
                nextMsg->GetMessageSize(&msgSize);
                // now we have to seek to the right position in the file and
                // basically re-initialize the transport with the correct message size.
                // then, we have to make sure the url keeps running somehow.
                nsCOMPtr<nsISupports> urlSupports = do_QueryInterface(m_runningUrl);
                //
                // put us in a state where we are always notified of incoming data
                //
                
                m_transport = 0; // open new stream transport
                m_inputStream = 0;
                m_outputStream = 0;
                
                rv = OpenMultipleMsgTransport(msgKey, msgSize);
                if (NS_SUCCEEDED(rv))
                {
                  if (!m_inputStream)
                    rv = m_transport->OpenInputStream(0, 0, 0, getter_AddRefs(m_inputStream));
                  
                  if (NS_SUCCEEDED(rv))
                  {
                    nsCOMPtr<nsIInputStreamPump> pump;
                    rv = NS_NewInputStreamPump(getter_AddRefs(pump), m_inputStream);
                    if (NS_SUCCEEDED(rv)) {
                      rv = pump->AsyncRead(this, urlSupports);
                      if (NS_SUCCEEDED(rv))
                        m_request = pump;
                    }
                  }
                }
                
                NS_ASSERTION(NS_SUCCEEDED(rv), "AsyncRead failed");
                if (m_loadGroup)
                  m_loadGroup->RemoveRequest(static_cast<nsIRequest *>(this), nsnull, aStatus);
                m_socketIsOpen = PR_TRUE; // mark the channel as open
                return aStatus;
              }
            }
          }
        }
        else
        {
        }
      }
    }
  }
  // and we want to mark ourselves for deletion or some how inform our protocol manager that we are 
  // available for another url if there is one.
  
  // mscott --> maybe we should set our state to done because we don't run multiple urls in a mailbox
  // protocol connection....
  m_nextState = MAILBOX_DONE;
  
  // the following is for smoke test purposes. QA is looking at this "Mailbox Done" string which
  // is printed out to the console and determining if the mail app loaded up correctly...obviously
  // this solution is not very good so we should look at something better, but don't remove this
  // line before talking to me (mscott) and mailnews QA....
  
  PR_LOG(MAILBOX, PR_LOG_ALWAYS, ("Mailbox Done\n"));
  
  // when on stop binding is called, we as the protocol are done...let's close down the connection
  // releasing all of our interfaces. It's important to remember that this on stop binding call
  // is coming from netlib so they are never going to ping us again with on data available. This means
  // we'll never be going through the Process loop...
  
  if (m_multipleMsgMoveCopyStream)
  {
    m_multipleMsgMoveCopyStream->Close();
    m_multipleMsgMoveCopyStream = nsnull;
  }
  nsMsgProtocol::OnStopRequest(request, ctxt, aStatus);
  return CloseSocket(); 
}