Exemple #1
0
static menuSound_t Keydown(menuFrameWork_t *self, int key)
{
    // ignore autorepeats
    if (Key_IsDown(key) > 1)
        return QMS_NOTHANDLED;

    switch (key) {
    case 'r':
        if (Key_IsDown(K_CTRL))
            return SetRconAddress();
        return QMS_NOTHANDLED;

    case 'c':
        if (Key_IsDown(K_CTRL))
            return CopyAddress();
        return QMS_NOTHANDLED;

    case K_SPACE:
        if (Key_IsDown(K_ALT) || !m_servers.list.numItems) {
            PingServers();
            return QMS_SILENT;
        }
        return PingSelected();

    case K_BACKSPACE:
        if (m_servers.pingstage) {
            FinishPingStage();
            return QMS_OUT;
        }
        return QMS_SILENT;

    default:
        return QMS_NOTHANDLED;
    }
}
Exemple #2
0
static void SendPacket(const IPX_Address *dest, const char *data, int length)
{
    int i;
    //WriteToLog("Sending packet of size %d", length);
    assert(length > 0);
    for (i = 0; i < 200 && m_sendPacket->ecb.inUseFlag; i++) {
        WriteToLog("SendPacket(): ecb in use flag != 0, impossible!!!");
        IPX_OnIdle();
    }

    memcpy(m_sendPacket->ecb.immediateAddress, dest->node, sizeof(dest->node));
    CopyAddress(&m_sendPacket->ipx.destination, dest);
    m_sendPacket->ecb.fragmentCount = 1;
    m_sendPacket->ecb.fragDesc[0].size = length + sizeof(SWOSPP_Packet) - sizeof(ECB);
    assert(m_sendPacket->ecb.fragDesc[0].size <= m_maxPacketSize);

    /* copy the data */
    memcpy(m_sendPacket->data, data, length);
    m_sendPacket->verifyStamp = 'SWPP';
    m_sendPacket->adler32Checksum = Adler32((const byte *)data, length);
    //HexDumpToLog((char *)m_sendPacket, sizeof(SWOSPP_Packet) + length, "next packet to send");

    IPX_Send((ECB *)m_sendPacket);
    if (m_sendPacket->ecb.completionCode)
        WriteToLog("Error sending packet! Code is %#02x", m_sendPacket->ecb.completionCode);
}
void CtrlDisAsmView::contextMenu(const QPoint &pos)
{
	QMenu menu(this);

	QAction *copyAddress = new QAction(tr("Copy &address"), this);
	connect(copyAddress, SIGNAL(triggered()), this, SLOT(CopyAddress()));
	menu.addAction(copyAddress);

	QAction *copyInstrHex = new QAction(tr("Copy instruction (&hex)"), this);
	connect(copyInstrHex, SIGNAL(triggered()), this, SLOT(CopyInstrHex()));
	menu.addAction(copyInstrHex);

	QAction *copyInstrDisAsm = new QAction(tr("Copy instruction (&disasm)"), this);
	connect(copyInstrDisAsm, SIGNAL(triggered()), this, SLOT(CopyInstrDisAsm()));
	menu.addAction(copyInstrDisAsm);

	menu.addSeparator();

	QAction *runToHere = new QAction(tr("&Run to here"), this);
	connect(runToHere, SIGNAL(triggered()), this, SLOT(RunToHere()));
	menu.addAction(runToHere);

	QAction *setNextStatement = new QAction(tr("&Set Next Statement"), this);
	connect(setNextStatement, SIGNAL(triggered()), this, SLOT(SetNextStatement()));
	menu.addAction(setNextStatement);

	QAction *toggleBreakpoint = new QAction(tr("&Toggle breakpoint"), this);
	connect(toggleBreakpoint, SIGNAL(triggered()), this, SLOT(ToggleBreakpoint()));
	menu.addAction(toggleBreakpoint);

	QAction *followBranch = new QAction(tr("&Follow branch"), this);
	connect(followBranch, SIGNAL(triggered()), this, SLOT(FollowBranch()));
	menu.addAction(followBranch);

	menu.addSeparator();

	//QAction *showDynarecResults = new QAction(tr("&Show Dynarec Results"), this);
	//connect(showDynarecResults, SIGNAL(triggered()), this, SLOT(ShowDynarecResults()));
	//menu.addAction(showDynarecResults);

	QAction *goToMemoryView = new QAction(tr("Go to in &Memory View"), this);
	connect(goToMemoryView, SIGNAL(triggered()), this, SLOT(GoToMemoryView()));
	menu.addAction(goToMemoryView);

	menu.addSeparator();

	//QAction *killFunction = new QAction(tr("&Kill function"), this);
	//connect(killFunction, SIGNAL(triggered()), this, SLOT(KillFunction()));
	//menu.addAction(killFunction);

	QAction *renameFunction = new QAction(tr("&Rename function..."), this);
	connect(renameFunction, SIGNAL(triggered()), this, SLOT(RenameFunction()));
	menu.addAction(renameFunction);


	menu.exec( mapToGlobal(pos));
}
Exemple #4
0
bool ConnectTo(const IPX_Address *dest)
{
    ClientAckId *c = FindClientAckId(dest);
    if (c) {
        ResetClientAckIds(c);
        return true;
    }

    /* shouldn't really happen */
    if (m_numClients >= MAX_CONNECTIONS)
        return false;

    c = &m_clientAckIds[m_numClients++];
    CopyAddress(&c->address, dest);
    ResetClientAckIds(c);
    WriteToLog("New connection to [%#.12s] established.", dest);
    return true;
}
Exemple #5
0
/* Add important packet that's about to be sent to the list of unacknowledged packets. */
char *AddUnacknowledgedPacket(const IPX_Address *address, dword id, byte type, const char *data, int size, int offset)
{
    UnAckPacket *p;
    assert(offset >= 0);
    assert(size + (int)sizeof(dword) + offset <= m_maxPacketSize);
    //WriteToLog("Adding unacknowledged packet to queue, for [%#.12s], id is %d", address, id);

    if (!(p = (UnAckPacket *)qAlloc(sizeof(UnAckPacket) + size + sizeof(dword) + offset)))
        return nullptr;

    p->size = size + sizeof(dword) + offset;
    CopyAddress(&p->address, address);
    p->next = m_unAckList;
    m_unAckList = p;
    *p->data = id;
    memcpy((char *)p->data + sizeof(dword) + offset, data, size);
    p->time = g_currentTick;
    p->type = type;
    return (char *)p->data;
}
Exemple #6
0
/** ReceivePacket

    destSize -> will contain the size of the packet after returning
    node     -> will contain sender's address after returning

    Return pointer to packet bytes allocated from the heap. Handle all incoming packet types.
    If there are no pending packets return nullptr. Also return nullptr if out of memory,
    differentiate that case by setting size to -1. Discard all invalid packets found.
*/
char *ReceivePacket(int *destSize, IPX_Address *node)
{
    dword id = 0, *currentId;
    int i, size;
    char *srcPtr, *destBuf = nullptr;

    /* ignoring malformed packets etc. */
    for (i = 0; i < MAX_RECV_PACKETS; i++)
        if (!m_packets[i]->ecb.inUseFlag && !m_packets[i]->ecb.completionCode)
            break;

    if (i >= MAX_RECV_PACKETS) {
        *destSize = 0;
        return nullptr;
    }

    size = htons(m_packets[i]->ipx.length) - sizeof(SWOSPP_Packet) + sizeof(ECB);
    /* our packets always have size limit */
    if (size < 0) {
        WriteToLog("Rejecting invalid size packet, with total size of %d bytes",
            htons(m_packets[i]->ipx.length));
        return ReceiveNextPacket(destSize, node, i);
    }

    srcPtr = m_packets[i]->data;
    /* get the sender's address and data */
    CopyAddress(node, &m_packets[i]->ipx.source);

    // can't have this if we're gonna let guys join the game
    //if (!FindClientAckId(node)) {
    //    WriteToLog("Rejecting packet from non-connected sender [%#.12s]", node);
    //    return ReceiveNextPacket(destSize, node, i);
    //}

    /* verify the stamp */
    if (m_packets[i]->verifyStamp != 'SWPP') {
        WriteToLog("Rejecting packet with invalid stamp: %08x:", m_packets[i]->verifyStamp);
        return ReceiveNextPacket(destSize, node, i);
    }

    /* this is probably overkill */
    if (m_packets[i]->adler32Checksum != Adler32((const byte *)m_packets[i]->data, size)) {
        WriteToLog("Rejecting packet with invalid Adler32 checksum (%d, expecting %d).",
            m_packets[i]->adler32Checksum, Adler32((const byte *)m_packets[i]->data, size));
        HexDumpToLog(m_packets[i]->data, size, "packet with failed checksum");
        return ReceiveNextPacket(destSize, node, i);
    }

    switch (m_packets[i]->type) {
    case UNIMPORTANT_PACKET_SIG:
        /* OK, with simple packet we're done already */
        break;

    case PARTIAL_PACKET_SIG:
    case IMPORTANT_PACKET_SIG:
        if (size < 4 + 5 * (m_packets[i]->type == PARTIAL_PACKET_SIG)) {
            WriteToLog("Malformed important/partial packet rejected, size = %d", size);
            return ReceiveNextPacket(destSize, node, i);
        }

        if (!(currentId = GetClientCurrentReceivingId(&m_packets[i]->ipx.source))) {
            WriteToLog("Rejecting important packet because client not connected.");
            HexDumpToLog(&m_packets[i]->ipx.source, sizeof(IPX_Address), "disconnected client address");
            /* maybe send them disconnect too for good measure? */
            DisconnectFrom(&m_packets[i]->ipx.source);
            return ReceiveNextPacket(destSize, node, i);
        }

        id = *(dword *)srcPtr;
        if (id > *currentId + 1) {
            /* OUT OF ORDER! YOU WILL OBEY! */
            //WriteToLog("Out of order packet detected, id = %d, expecting %d", id, *currentId + 1);
            return ReceiveNextPacket(destSize, node, i);
        }

        if (id == *currentId + 1) {
            /* cool, this is expected next packet, bump id and send it up there */
            size -= sizeof(dword);
            srcPtr += sizeof(dword);

            /* now process fragmented packet, if it is one */
            if (m_packets[i]->type == PARTIAL_PACKET_SIG) {
                byte total;
                dword fragId;

                if (size < 6) {
                    WriteToLog("Malformed partial packet rejected, size = %d.", size);
                    return ReceiveNextPacket(destSize, node, i);
                }

                fragId = *(dword *)srcPtr;
                total = srcPtr[4];

                if (total > MAX_FRAGMENTS) {
                    WriteToLog("Too many fragments for partial packet (%d).", total);
                    return ReceiveNextPacket(destSize, node, i);
                }

                size -= 5;
                srcPtr += 5;

                /* in case of memory exhaustion don't send ack, they'll send it again
                   and we'll hopefully have enough memory by then */
                if (!(destBuf = AddPacketFragment(destSize, srcPtr, size, node, fragId, total))) {
                    if (*destSize >= 0) {
                        ++*currentId;
                        SendAck(&m_packets[i]->ipx.source, id);
                    }

                    return ReceiveNextPacket(destSize, node, i);
                }

                /* we've got a fully assembled packet from fragments now */
                srcPtr = destBuf;
                size = *destSize;
            }
            ++*currentId;
            //WriteToLog("Increasing current id for node [%#.12s], id is %d now.", &m_packets[i]->ipx.source, *currentId);
        } else {
            /* we've already processed this one, get next */
            //WriteToLog("Discarding packet with ID %d (already processed, cur. id = %d)", id, *currentId);
            SendAck(&m_packets[i]->ipx.source, id);
            return ReceiveNextPacket(destSize, node, i);
        }
        break;

    case ACK_PACKET_SIG:
        if (size != 4)
            WriteToLog("Discarding ack packet with invalid size (%d)", size);
        else {
            AcknowledgePacket(*(dword *)srcPtr, &m_packets[i]->ipx.source);
        }

        return ReceiveNextPacket(destSize, node, i);

    case CANCEL_PARTIAL_SIG:
        if (size != sizeof(dword))
            WriteToLog("Received partial cancellation packet with invalid size: %d", size);
        else
            CancelFragmentedPacket(&m_packets[i]->ipx.source, *(dword *)srcPtr);
        return ReceiveNextPacket(destSize, node, i);
        break;

    default:
        WriteToLog("Invalid packet type: %#x", m_packets[i]->type);
        return ReceiveNextPacket(destSize, node, i);
    }

    if (!destBuf)
        destBuf = (char *)qAlloc(size);

    if (!destBuf) {
        *destSize = -1; /* signal memory exhaustion */
        return nullptr;
    }

    /* only ack if we're sure everything went well */
    if (m_packets[i]->type == PARTIAL_PACKET_SIG || m_packets[i]->type == IMPORTANT_PACKET_SIG)
        SendAck(&m_packets[i]->ipx.source, id);

    if (m_packets[i]->type != PARTIAL_PACKET_SIG) {
        *destSize = size;
        memcpy(destBuf, srcPtr, size);
    }

    //WriteToLog("Source address: [%#.12s]", node);
    //HexDumpToLog(m_packets[i], size + sizeof(SWOSPP_Packet), "received packet data");
    IPX_Listen((ECB *)m_packets[i]);
    return destBuf;
}
Exemple #7
0
/** InitializeNetwork

    Initialize the whole network subsystem. Do IPX installation check,
    determine maximum driver packet size and allocate buffer that has to be in
    low memory in order to be accessible by the IPX network driver. Open our
    socket on dynamically assigned port. Return string error description, or
    nullptr if all went well.

    Memory layout of low memory:
    +--------------------------------+
    |                                |
    | buffer for receiving packets,  |
    | sized dynamically              |
    |                                |
    |--------------------------------|
    | buffer for sending packet      |
    | (1 fragment descriptor -       |
    |  maximum size)                 |
    +--------------------------------|
    | our local ipx address          |
    +--------------------------------+
*/
const char *InitializeNetwork()
{
    if (!IPX_IsInstalled())
        return "IPX compatible network not detected.";

    if (m_lowMemory)      /* if this isn't nullptr we're initialized already */
        return nullptr;

    /* -1 cause DOSBox actually rejects packets of max size */
    if ((m_maxPacketSize = IPX_GetMaximumPacketSize() - 1) < (int)sizeof(IPX_Header) + 128)
        return "Insufficient IPX packet size.";

    WriteToLog("IPX maximum packet size is %d.", m_maxPacketSize);
    /* allocate 1 more byte for receiving buffer just in case (DOSBox receive() allows full size) */
    int lowMemorySize = MAX_RECV_PACKETS * (sizeof(ECB) + (m_maxPacketSize + 1));
    m_sendPacket = (SWOSPP_Packet *)lowMemorySize;
    lowMemorySize += sizeof(ECB) + m_maxPacketSize + 1 + sizeof(IPX_Address);
    m_lowMemory = (char *)AllocateLowMemory(lowMemorySize);
    if (!m_lowMemory)
        return "Failed to allocate DOS memory.";

    WriteToLog("%d bytes of low memory allocated, at %#x", lowMemorySize, m_lowMemory);
    /* got the memory, now initialize it and set up all the pointers */
    memset(m_lowMemory, 0, lowMemorySize);
    /* initialize send buffer, we can only send 1 max size descriptor anyway */
    m_sendPacket = (SWOSPP_Packet *)(m_lowMemory + (int)m_sendPacket);
    m_sendPacket->ecb.fragmentCount = 1;
    m_sendPacket->ecb.fragDesc[0].address[0] = (char *)(&m_sendPacket->ipx) - m_lowMemory;
    m_sendPacket->ecb.fragDesc[0].address[1] = (uint)m_lowMemory >> 4;

    /* get the port dynamically */
    if ((m_socketId = IPX_OpenSocket()) == -1) {
        FreeLowMemory(m_lowMemory);
        m_lowMemory = nullptr;
        return "Failed to open socket.";
    }

    /* and finally, space for our IPX address */
    m_ourAddress = IPX_GetInterNetworkAddress((char *)m_sendPacket + sizeof(ECB) + m_maxPacketSize + 1);
    m_ourAddress->socket = m_socketId;
    HexDumpToLog((char *)m_ourAddress, sizeof(IPX_Address), "our IPX address");

    /* set up receiving ECBs */
    for (int i = 0; i < MAX_RECV_PACKETS; i++) {
        m_packets[i] = (SWOSPP_Packet *)(m_lowMemory + i * (sizeof(ECB) + m_maxPacketSize));
        m_packets[i]->ecb.socketNumber = m_socketId;
        m_packets[i]->ecb.fragmentCount = 1;
        m_packets[i]->ecb.fragDesc[0].address[0] = (uint)&m_packets[i]->ipx - (uint)m_lowMemory;
        m_packets[i]->ecb.fragDesc[0].address[1] = (uint)m_lowMemory >> 4;
        m_packets[i]->ecb.fragDesc[0].size = m_maxPacketSize;
        IPX_Listen((ECB *)m_packets[i]);
    }

    /* set up broadcast node */
    CopyAddress(&m_broadcastAddress, m_ourAddress);
    memset(m_broadcastAddress.node, -1, sizeof(m_broadcastAddress.node));

    /* finish setting up sending ECB */
    m_sendPacket->ecb.socketNumber = m_socketId;
    m_sendPacket->verifyStamp = 'SWPP';
    CopyAddress(&m_sendPacket->ipx.source, m_ourAddress);
    m_clientAckIds = (ClientAckId *)qAlloc(MAX_CONNECTIONS * sizeof(ClientAckId));
    m_numClients = 0;

    /* phew... all OK */
    return nullptr;
}
Exemple #8
0
/** AddPacketFragment

    bufSize -> size of returned allocated buffer, if this was last fragment
    data    -> contents of packet fragment
    length  -  length of this fragment's data
    source  -  sender's address
    fragID  -  ID of the whole fragment group
    total   -  total number of fragments for this group

    Packet fragment successfully received. It is guaranteed to be unique and in
    the right order. See if we can assemble full packet, return pointer to it if
    so (memory will be allocated from heap and caller should free it when done).
    If this wasn't last fragment, just return nullptr and store it for later. In
    case buffer of sufficient size could not be allocated, it will be ignored
    without an ack, in hope we'll have enough memory when the sender sends it
    back again. Length will be set to -1 to indicate this situation to the
    caller.
*/
static char *AddPacketFragment(int *bufSize, char *data, int length,
    const IPX_Address *source, dword fragId, int total)
{
    FragmentLink *p, *prev;
    *bufSize = 0;
    FindFragmentStart(source, fragId, &p, &prev);

    if (!p) {
        /* first fragment of a packet arrived */
        p = (FragmentLink *)qAlloc(sizeof(FragmentLink) + length);

        if (!p) {
            WriteToLog("Out of memory while trying to store packet fragment!");
            *bufSize = -1;
            return nullptr;
        }

        p->next = m_fragmentList;
        m_fragmentList = p;
        CopyAddress(&p->address, source);
        p->fragmentId = fragId;
        p->partsReceived = 1;
        p->totalParts = total;
        p->totalSize = length;
        p->lastFragment = nullptr;
        p->first.dataSize = length;
        p->first.next = nullptr;
        memcpy(&p->first.data, data, length);
        return nullptr;
    } else {
        Fragment *q;
        /* we already have at least some previous fragment(s) for this group */
        if (p->partsReceived + 1 == total) {
            /* this is the last fragment, we can recreate original packet */
            char *bufPtr, *curPtr;

            *bufSize = p->totalSize + length;
            if (!(bufPtr = (char *)qAlloc(*bufSize))) {
                WriteToLog("Insufficient memory to assemble packet (needs %d bytes).", *bufSize);
                *bufSize = -1;
                return nullptr;
            }

            /* assemble packet and signal it */
            for (curPtr = bufPtr, q = &p->first; q; q = q->next) {
                memcpy(curPtr, q->data, q->dataSize);
                curPtr += q->dataSize;
            }

            memcpy(curPtr, data, length);
            RemoveFragmentList(p, prev);
            return bufPtr;
        } else {
            /* store this fragment to the end of the list */
            auto q = (Fragment *)qAlloc(sizeof(Fragment) + length);
            if (!q) {
                WriteToLog("Out of memory while trying to store packet fragment!");
                *bufSize = -1;
                return nullptr;
            }

            q->dataSize = length;
            q->next = nullptr;
            memcpy(q->data, data, length);

            if (p->lastFragment)
                p->lastFragment->next = q;
            else
                p->first.next = q;

            p->lastFragment = q;
            p->partsReceived++;
            p->totalSize += length;
            return nullptr;
        }
    }

    return nullptr;
}
Exemple #9
0
void GetOurAddress(IPX_Address *dest)
{
    CopyAddress(dest, m_ourAddress);
}
Exemple #10
0
int main(int iArgCount, char *pszArgs[])
{
    int iVarLength = 0;
    FILE *pInFile = stdin;
    char *pszMailRoot;
    char szMailRoot[SYS_MAX_PATH] = "";

    /* Initialize time */
    tzset();

    if ((pszMailRoot = SysGetEnv(ENV_MAIL_ROOT)) == NULL ||
        (iVarLength = (int)strlen(pszMailRoot)) == 0) {
        free(pszMailRoot);
        fprintf(stderr, "cannot find environment variable: %s\n",
            ENV_MAIL_ROOT);
        return 1;
    }
    StrSNCpy(szMailRoot, pszMailRoot);
    if (szMailRoot[iVarLength - 1] != SYS_SLASH_CHAR)
        strcat(szMailRoot, SYS_SLASH_STR);
    free(pszMailRoot);

    /* Parse command line */
    int i;
    bool bExtractRcpts = false;
    bool bXMailFormat = false;
    bool bDotMode = true;
    char szMailFrom[256] = "";
    char szExtMailFrom[256] = "";
    char szInputFile[SYS_MAX_PATH] = "";
    char szRcptFile[SYS_MAX_PATH] = "";

    SysGetUserAddress(szMailFrom, sizeof(szMailFrom) - 1, ENV_DEFAULT_DOMAIN);

    for (i = 1; i < iArgCount; i++) {
        if (strcmp(pszArgs[i], "--") == 0) {
            ++i;
            break;
        }

        if (strcmp(pszArgs[i], "--rcpt-file") == 0) {
            if (++i < iArgCount)
                StrSNCpy(szRcptFile, pszArgs[i]);
        } else if (strcmp(pszArgs[i], "--xinput-file") == 0) {
            if (++i < iArgCount) {
                StrSNCpy(szInputFile, pszArgs[i]);

                bXMailFormat = true;
            }
        } else if (strcmp(pszArgs[i], "--input-file") == 0) {
            if (++i < iArgCount)
                StrSNCpy(szInputFile, pszArgs[i]);
        } else if (strcmp(pszArgs[i], "-i") == 0 ||
               strcmp(pszArgs[i], "-oi") == 0) {
            bDotMode = false;
        } else if (strcmp(pszArgs[i], "-t") == 0) {
            bExtractRcpts = true;
        } else if (strncmp(pszArgs[i], "-f", 2) == 0) {
            if (pszArgs[i][2] != '\0')
                CopyAddress(szMailFrom, pszArgs[i] + 2,
                        sizeof(szMailFrom) - 1);
            else if ((i + 1) < iArgCount) {
                CopyAddress(szMailFrom, pszArgs[i + 1],
                        sizeof(szMailFrom) - 1);
                i++;
            }
        } else if (strncmp(pszArgs[i], "-F", 2) == 0) {
            if (pszArgs[i][2] != '\0')
                StrSNCpy(szExtMailFrom, pszArgs[i] + 2);
            else if (i + 1 < iArgCount) {
                StrSNCpy(szExtMailFrom, pszArgs[i + 1]);
                i++;
            }

            char const *pszOpen = strchr(szExtMailFrom, '<');

            if (pszOpen == NULL)
                CopyAddress(szMailFrom, szExtMailFrom,
                        sizeof(szMailFrom) - 1);
            else {
                char szTmpMailFrom[256];

                StrSNCpy(szTmpMailFrom, pszOpen + 1);

                char *pszClose =
                    (char *) strchr(szTmpMailFrom, '>');

                if (pszClose != NULL)
                    *pszClose = '\0';

                CopyAddress(szMailFrom, szTmpMailFrom,
                        sizeof(szMailFrom) - 1);
            }
        } else if (strncmp(pszArgs[i], "-o", 2) == 0) {

        } else if (strcmp(pszArgs[i], "-L") == 0 ||
               strcmp(pszArgs[i], "-O") == 0 ||
               strcmp(pszArgs[i], "-R") == 0 ||
               strcmp(pszArgs[i], "-X") == 0 ||
               strcmp(pszArgs[i], "-V") == 0 ||
               strcmp(pszArgs[i], "-N") == 0 ||
               strncmp(pszArgs[i], "-qG", 3) == 0 ||
               strncmp(pszArgs[i], "-q!", 3) == 0) {
            if (i + 1 < iArgCount)
                i++;
        } else
            break;
    }

    /* Save recipients index and counter */
    int iRcptIndex, iRcptCount;

    iRcptIndex = Min(i, iArgCount);
    iRcptCount = iArgCount - iRcptIndex;

    /* Check if recipients are supplied */
    if (!bExtractRcpts && iRcptCount == 0 && IsEmptyString(szRcptFile)) {
        fprintf(stderr, "empty recipient list\n");
        return 2;
    }

    if (!IsEmptyString(szInputFile)) {
        if ((pInFile = fopen(szInputFile, "rb")) == NULL) {
            perror(szInputFile);
            return 3;
        }
    }

        /* Check if the sender is specified */
        if (IsEmptyString(szMailFrom)) {
                char const *pszUser = SysGetEnv(ENV_USER);

                if (pszUser == NULL)
                        pszUser = "******";
                CopyAddress(szMailFrom, pszUser, sizeof(szMailFrom) - 1);
        }

    /* Create file name */
    char szHostName[256] = "";
    char szDataFile[SYS_MAX_PATH] = "";
    char szMailFile[SYS_MAX_PATH] = "";

    SysGetHostName(szHostName, sizeof(szHostName) - 1);

    SysSNPrintf(szDataFile, sizeof(szDataFile), "%s%s%lu000.%lu.%s",
            szMailRoot, LOCAL_TEMP_SUBPATH, (unsigned long) time(NULL),
            SysGetProcessId(), szHostName);
    SysSNPrintf(szMailFile, sizeof(szMailFile), "%s.mail", szDataFile);

    /* Open raw data file */
    FILE *pDataFile = fopen(szDataFile, "w+b");

    if (pDataFile == NULL) {
        perror(szDataFile);
        if (pInFile != stdin)
            fclose(pInFile);
        return 4;
    }
    /* Open maildrop file */
    FILE *pMailFile = fopen(szMailFile, "wb");

    if (pMailFile == NULL) {
        perror(szMailFile);
        fclose(pDataFile);
        remove(szDataFile);
        if (pInFile != stdin)
            fclose(pInFile);
        return 5;
    }
    fprintf(pMailFile, "mail from:<%s>\r\n", szMailFrom);

    for (i = iRcptIndex; i < iArgCount; i++) {
        char szAddr[256];

        CopyAddress(szAddr, pszArgs[i], sizeof(szAddr) - 1);
        fprintf(pMailFile, "rcpt to:<%s>\r\n", szAddr);
    }

    int iLine;
    bool bInHeaders = true;
    bool bHasFrom = false;
    bool bHasDate = false;
    bool bRcptSource = false;
    bool bNoEmit = false;
    char szBuffer[1536];

    for (iLine = 0; fgets(szBuffer, sizeof(szBuffer) - 1, pInFile) != NULL; iLine++) {
        int iLineLength = (int)strlen(szBuffer);

        for (; iLineLength > 0 && (szBuffer[iLineLength - 1] == '\r' ||
                       szBuffer[iLineLength - 1] == '\n'); iLineLength--);

        szBuffer[iLineLength] = '\0';

        /* Is it time to stop reading ? */
        if (bDotMode && strcmp(szBuffer, ".") == 0)
            break;

        /* Decode XMail spool file format */
        if (bXMailFormat) {
            if (strcmp(szBuffer, MAIL_DATA_TAG) == 0)
                bXMailFormat = false;

            continue;
        }
        /* Extract mail from */
        if (bInHeaders) {
            bool bStraightFile = false;

            if ((iLine == 0) && !IsRFC822HeaderLine(szBuffer))
                bStraightFile = true;

            if (bStraightFile || iLineLength == 0) {
                bInHeaders = false;
                bNoEmit = false;

                /* Add mail from (if not present) */
                if (!bHasFrom) {
                    if (strlen(szExtMailFrom) != 0)
                        fprintf(pDataFile, "From: %s\r\n", szExtMailFrom);
                    else
                        fprintf(pDataFile, "From: <%s>\r\n", szMailFrom);
                }
                /* Add date (if not present) */
                if (!bHasDate) {
                    char szDate[128] = "";

                    GetTimeStr(szDate, sizeof(szDate) - 1, time(NULL));
                    fprintf(pDataFile, "Date: %s\r\n", szDate);
                }

                if (bStraightFile)
                    fprintf(pDataFile, "\r\n");
            }

            if (szBuffer[0] == ' ' || szBuffer[0] == '\t') {
                if (bExtractRcpts && bRcptSource) {
                    int iRcptCurr = EmitRecipients(pMailFile, szBuffer);

                    if (iRcptCurr > 0)
                        iRcptCount += iRcptCurr;
                }
            } else if (iLineLength > 0) {
                bNoEmit = (strnicmp(szBuffer, "Bcc:", 4) == 0);
                bRcptSource = strnicmp(szBuffer, "To:", 3) == 0 ||
                    strnicmp(szBuffer, "Cc:", 3) == 0 ||
                    strnicmp(szBuffer, "Bcc:", 4) == 0;

                if (bExtractRcpts && bRcptSource) {
                    int iRcptCurr = EmitRecipients(pMailFile, szBuffer);

                    if (iRcptCurr > 0)
                        iRcptCount += iRcptCurr;
                }

                if (!bHasFrom && strnicmp(szBuffer, "From:", 5) == 0)
                    bHasFrom = true;

                if (!bHasDate && strnicmp(szBuffer, "Date:", 5) == 0)
                    bHasDate = true;
            }
        }
        if (!bNoEmit)
            fprintf(pDataFile, "%s\r\n", szBuffer);
    }

    /* Close input file if different from stdin */
    if (pInFile != stdin)
        fclose(pInFile);

    /* Dump recipient file */
    if (!IsEmptyString(szRcptFile)) {
        FILE *pRcptFile = SafeOpenFile(szRcptFile, "rb");

        if (pRcptFile == NULL) {
            perror(szRcptFile);
            fclose(pDataFile);
            remove(szDataFile);
            fclose(pMailFile);
            remove(szMailFile);
            return 6;
        }

        while (fgets(szBuffer, sizeof(szBuffer) - 1, pRcptFile) != NULL) {
            int iLineLength = (int)strlen(szBuffer);

            for (; iLineLength > 0 &&
                     (szBuffer[iLineLength - 1] == '\r' ||
                      szBuffer[iLineLength - 1] == '\n'); iLineLength--);

            szBuffer[iLineLength] = '\0';

            if (iLineLength >= MAX_ADDR_NAME)
                continue;

            /*
               [i_a] '@' is also accepted in the section before the '<email-address>', e.g.
               "loony@toones <*****@*****.**>"

               Besides, this code must be able to handle lines like
               'from bla <*****@*****.**>; via blub ([email protected]); etc.'
             */
            char const *lt_p = strchr(szBuffer, '<');
            char const *gt_p = (!lt_p ? lt_p : strchr(lt_p + 1, '>'));
            char const *pszAt = strchr(lt_p ? lt_p + 1 : szBuffer, '@');
            while (lt_p && gt_p && pszAt) {
                if (pszAt > gt_p) {
                    lt_p = strchr(lt_p + 1, '<');
                    gt_p = (!lt_p ? lt_p : strchr(lt_p + 1, '>'));
                    pszAt = (!lt_p ? /* copout for bad line */ strchr(szBuffer, '@') : strchr(lt_p + 1, '@'));
                }
                else {
                    break;
                }
            }

            if (pszAt == NULL)
                continue;

            char szRecipient[MAX_ADDR_NAME] = "";

            if (AddressFromAtPtr(pszAt, szBuffer, szRecipient,
                         sizeof(szRecipient)) != NULL) {
                fprintf(pMailFile, "rcpt to:<%s>\r\n", szRecipient);

                ++iRcptCount;
            }
        }

        fclose(pRcptFile);
    }
    /* Check the number of recipients */
    if (iRcptCount == 0) {
        fprintf(stderr, "empty recipient list\n");
        fclose(pDataFile);
        remove(szDataFile);
        fclose(pMailFile);
        remove(szMailFile);
        return 7;
    }
    /* Empty line separator between maildrop header and data */
    fprintf(pMailFile, "\r\n");

    /* Append data file */
    rewind(pDataFile);

    unsigned int uReaded;

    do {
        if (((uReaded = (unsigned int)fread(szBuffer, 1, (int)sizeof(szBuffer), pDataFile)) != 0) &&
            (fwrite(szBuffer, 1, uReaded, pMailFile) != uReaded)) {
            perror(szMailFile);
            fclose(pDataFile);
            remove(szDataFile);
            fclose(pMailFile);
            remove(szMailFile);
            return 8;
        }

    } while (uReaded == sizeof(szBuffer));

    fclose(pDataFile);
    remove(szDataFile);

    /* Sync and close the mail file */
    if (SysFileSync(pMailFile) < 0 || fclose(pMailFile)) {
        remove(szMailFile);
        fprintf(stderr, "cannot write file: %s\n", szMailFile);
        return 9;
    }
    /* Move the mail file */
    char szDropFile[SYS_MAX_PATH];

    SysSNPrintf(szDropFile, sizeof(szDropFile), "%s%s%lu000.%lu.%s",
            szMailRoot, LOCAL_SUBPATH, (unsigned long) time(NULL),
            SysGetProcessId(), szHostName);
    if (SysMoveFile(szMailFile, szDropFile) < 0) {
        remove(szMailFile);
        fprintf(stderr, "cannot move file: %s\n", szMailFile);
        return 10;
    }

    return 0;
}
Exemple #11
0
//---------------------------------------------------------------------------
void __fastcall TFMain_11011981::miCopyAddressIClick(TObject *Sender)
{
    CopyAddress(lbUnitItems->Items->Strings[lbUnitItems->ItemIndex], 1, 8);    
}
Exemple #12
0
 void SetBroadcastAddress(int family, const void* data, size_t byteCount) {
     ifa.ifa_dstaddr = CopyAddress(family, data, byteCount, &ifa_ifu);
 }
Exemple #13
0
 void SetAddress(int family, const void* data, size_t byteCount) {
     ifa.ifa_addr = CopyAddress(family, data, byteCount, &addr);
 }