THREAD_FUNC AuxDataToIDA8Thread(void *argptr)
{
long *out;
int  nsamp;
OLD_MSGQ_MSG *SampleMsg, *BufferMsg;
ISPD_AUX_DATUM sample;
ISPD_AUX_HANDLE *ap;
static char *fid = "AuxDataToIDA8Thread";

    util_log(2, "%s thread started, tid = %d", fid, THREAD_SELF());

    ap = (ISPD_AUX_HANDLE *) argptr;

    nsamp = 0;

    while (1) {

    /* Grap the next aux sample */

        SampleMsg = msgq_get(ap->q.full, OLD_MSGQ_WAITFOREVER);
        if (!msgq_chkmsg2(fid, SampleMsg)) {
            util_log(1, "%s: corrupt message received", fid);
            ispd_die(MY_MOD_ID + 4);
        }

    /* Copy it to local storage */

        sample = *((ISPD_AUX_DATUM *) SampleMsg->data);
        msgq_put(ap->q.empty, SampleMsg);

    /* If starting a new packet, grab empty buffer from heap and init */

        if (nsamp == 0) {
            BufferMsg = msgq_get(&Heap->packets, OLD_MSGQ_WAITFOREVER);
            if (!msgq_chkmsg2(fid, BufferMsg)) {
                util_log(1, "%s: corrupt message received", fid);
                ispd_die(MY_MOD_ID + 1);
            }
            out = (long *) StartIDA8Packet(ap, &sample, BufferMsg->data);
        }

    /* Append uncompressed samples to packet until done */

        out[nsamp++] = htonl(sample.value);
        if (nsamp == MAXSAMP) {
            FinishIDA8Packet(ap, nsamp, &sample, BufferMsg->data);
            msgq_put(&Q->das_process, BufferMsg);
            MUTEX_LOCK(&Status->lock);
                ++ap->stat->nrec;
            MUTEX_UNLOCK(&Status->lock);
            nsamp = 0;
        }
    }
}
Exemple #2
0
void
lookup_result_fd_readable(void)
{
    int res;

    res = msgq_read(lookup_result_mq);
    if (res == 0 || (res < 0 && errno != EAGAIN)) {
        warn_socket_error(res, false, "lookup result pipe");
        running = false;
        return;
    }
    while (msgq_has_complete_msg(lookup_result_mq)) {
        int rc;
        void *data;
        size_t size;
        struct addrinfo *ai;
        DCLookup *lookup;

        msgq_get(lookup_result_mq, MSGQ_INT, &rc, MSGQ_BLOB, &data, &size, MSGQ_END);
        ai = data_to_addrinfo(data, size);
        free(data);
        lookup = (DCLookup*) ptrv_remove_first(pending_lookups);
        if (!lookup->cancelled)
            lookup->callback(rc, ai, lookup->data);
        free(lookup);
        free_read_addrinfo(ai);
    }
}
Exemple #3
0
lookup_main(int request_fd[2], int result_fd[2])
{
    MsgQ *request_mq;
    MsgQ *result_mq;
    struct sigaction sigact;

    close(request_fd[1]);
    close(result_fd[0]);
    request_mq = msgq_new(request_fd[0]);
    result_mq = msgq_new(result_fd[1]);

    /* Inability to register these signals is not a fatal error. */
    sigact.sa_flags = SA_RESTART;
    sigact.sa_handler = SIG_IGN;
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
    sigact.sa_restorer = NULL;
#endif
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);
    sigaction(SIGUSR1, &sigact, NULL);
    sigaction(SIGCHLD, &sigact, NULL);
    sigaction(SIGPIPE, &sigact, NULL);

    while (msgq_read_complete_msg(request_mq) > 0) {
        char *node;
        char *service;
        void *data;
        size_t size;
        struct addrinfo *hints_ai;
        struct addrinfo *result_ai = NULL;
        int rc;

        /* XXX: msgq_get_sync, check its result, and use for (;;) */
        msgq_get(request_mq, MSGQ_STR, &node, MSGQ_STR, &service, MSGQ_BLOB, &data, &size, MSGQ_END);
        hints_ai = data_to_addrinfo(data, size);
        rc = getaddrinfo(node, service, hints_ai, &result_ai);
        free(node);
        free(service);
        free_read_addrinfo(hints_ai);
        free(data);
        addrinfo_to_data(result_ai, &data, &size);
        /* XXX: msgq_put_sync, check its result, and get rid of msgq_write_all */
        msgq_put(result_mq, MSGQ_INT, rc, MSGQ_BLOB, data, size, MSGQ_END);
        free(data);
        if (msgq_write_all(result_mq) < 0)
            break;
    }

    /* msgq_read_complete_msg may have failed if it returned < 0.
     * But we can't print any errors from this process (it would
     * interfere with the readline-managed display, so just exit
     * gracefully.
     */

    msgq_free(request_mq);
    msgq_free(result_mq);
    close(request_fd[0]);
    close(result_fd[1]);
    exit(EXIT_SUCCESS);
}
Exemple #4
0
void * reader_start(void * usr)
{
    /* real time thread */
    uint32_t buf[16];
    int n = 0;
    int a = 0;
    while(1)
    {
        /* ok to block for work here */
        msgq_get(replyq, buf, sizeof(buf));
        if(buf[0] == TICK)
        {
            printf("%s %d\n", tag_name[buf[0]], buf[1]);
        }
        buf[0] = a;
        buf[1] = n;
        int r = msgq_tryput(clientq, buf, sizeof(buf));
        if(r < 0)
        {
            n++;
        }
        else
        {
            a++;
        }
    }
}
Exemple #5
0
void * socket_start(void * usr)
{
    uint32_t msg[2] = {0, 0};
    while(1)
    {
        msgq_get(clientq, msg, sizeof(msg));
        printf("data %d %d\n", msg[0], msg[1]);
        usleep(100000);
    }
    return 0;
}
static void ServiceConnection()
{
char peer[IDA_MAXRECLEN];
char empty[IDA_MAXRECLEN];
int done, count;
OLD_MSGQ_MSG *msg;
OLD_MSGQ *dest;
static char *fid = "isp_inject:ServceConnection";

    util_peer(client, peer, IDA_MAXRECLEN);
    util_log(1, "injection request from %s", peer);
    memset(empty, 0, IDA_MAXRECLEN);

    util_noblock(client);
    done = count = 0;
    while (!done) {
        msg = msgq_get(&Heap->packets, OLD_MSGQ_WAITFOREVER);
        if (!msgq_chkmsg2(fid, msg)) {
            util_log(1, "%s: corrupt Heap->packets message received", fid);
            ispd_die(MY_MOD_ID + 1);
        }
        if (util_read(client, msg->data, IDA_BUFSIZ, 10) == IDA_BUFSIZ) { /* IDA10 OK */
            if (memcmp(msg->data, empty, IDA_BUFSIZ) == 0) { /* IDA10 OK */
                done = 1;
                dest = &Heap->packets;
            } else {
                ++count;
                MUTEX_LOCK(&Status->lock);
                    ++Status->count.njec;
                MUTEX_UNLOCK(&Status->lock);
                dest = &Q->das_process;
            }
        } else {
            util_log(1, "read error from %s: %s", peer, syserrmsg(errno));
            done = 1;
            dest = &Heap->packets;
        }
        msgq_put(dest, msg);
    }

    util_log(1, "%d records received from %s", count, peer);
}
Exemple #7
0
int
main(void)
{
    MsgQ_t      Q;
    MsgQ_t*     pQ = NULL;
    MsgQ_t      zeroed_q;
    MsgQ_t      bogus_q;
    MsgQ_t      valid_q;
    Message_t   Msg;
    Message_t   NullMsg;
    Message_t   Req_m;
    Message_t*  pMsg = NULL;
    Message_t*  pNULLMsg = NULL;
    Message_t   zeroed_m;
    Message_t   bogus_m;
    Message_t   array_m[3];
    IpmbReq_t*  pReq     = (IpmbReq_t*)(Req_m.Data);
    size_t      old_head;
    size_t      old_tail;

    bzero(&zeroed_q, sizeof(zeroed_q));
    bzero(&zeroed_m, sizeof(zeroed_m));
    bzero(&Req_m, sizeof(Req_m));
    bzero(&array_m, sizeof(array_m));
    bzero(&NullMsg, sizeof(NullMsg));
    memset(&bogus_m, 1, sizeof(bogus_m));
    memset(&bogus_q, 1, sizeof(bogus_q));
    Q = bogus_q;
    valid_q = zeroed_q;

    Req_m.DstAddr = 0x24;
    Req_m.Length = sizeof(IpmbReq_t) + 1UL;
    pReq->NetFn = 0x6 << 2;
    pReq->MasterAddr = 0x10;
    pReq->SeqNum = 0x30;
    pReq->Command = 1;
    checksum(&Req_m);


    plan(56);

    Msg = NullMsg;
    ok(EINVAL == msgq_get(pQ, &Msg), "get returns error when passed NULL Q pointer");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message block untouched");
    ok(0 == mock_pthread_mutex_lock_count, "pthread_mutex_lock not called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    ok(0 == msgq_init(&valid_q, 2), "Successfully initialized Message Q");
    Msg = Req_m;
    ok(0 == msgq_post(&valid_q, &Msg), "Successfully posted single valid message");
    pMsg = valid_q.queue;
    memcpy(array_m, pMsg, sizeof(array_m));
    Q = valid_q;
    mock_pthread_mutex_lock_count = mock_pthread_mutex_unlock_count = 0;
    ok(EINVAL == msgq_get(&Q, pNULLMsg), "get returns error when passed NULL message pointer");
    ok(valid_q.queue == pMsg, "queue pointer didn't change");
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q block untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == mock_pthread_mutex_lock_count, "pthread_mutex_lock not called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    mock_pthread_mutex_lock_count = mock_pthread_mutex_unlock_count = 0;
    ok(EINVAL == msgq_get(pQ, pNULLMsg), "get returns error when passed NULL message & Q pointers");
    ok(0 == mock_pthread_mutex_lock_count, "pthread_mutex_lock not called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    valid_q.queue = pMsg;
    Q = valid_q;
    Msg = NullMsg;
    memcpy(pMsg, array_m, sizeof(array_m));
    // corrupt by removing queue
    Q.queue = NULL;
    ok(EINVAL == msgq_get(&Q, &Msg), "get returns error when Q's queue is NULL");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message was untouched");
    Q.queue = pMsg;
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q was untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == mock_pthread_mutex_lock_count, "pthread_mutex_lock not called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    valid_q.queue = pMsg;
    Q = valid_q;
    Msg = NullMsg;
    memcpy(pMsg, array_m, sizeof(array_m));
    // corrupt size
    Q.size = 1;
    ok(EINVAL == msgq_get(&Q, &Msg), "get returns error when Q's size is < 2");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message was untouched");
    Q.size = valid_q.size;
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q was untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == mock_pthread_mutex_lock_count, "pthread_mutex_lock not called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    valid_q.queue = pMsg;
    Q = valid_q;
    Msg = NullMsg;
    memcpy(pMsg, array_m, sizeof(array_m));
    mock_pthread_mutex_lock_failure = EIO;
    mock_pthread_mutex_lock_count = 0;
    ok(EIO == msgq_get(&Q, &Msg), "get returns error on pthread_mutex_lock failure");
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q was untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message was untouched");
    ok(1 == mock_pthread_mutex_lock_count, "pthread_mutex_lock was called");
    ok(0 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock not called");

    valid_q.queue = pMsg;
    Q = valid_q;
    Msg = NullMsg;
    old_head = Q.head;
    old_tail = Q.tail;
    Q.head = Q.tail;
    memcpy(pMsg, array_m, sizeof(array_m));
    mock_pthread_mutex_lock_failure = 0;
    mock_pthread_cond_wait_failure = EINTR;
    mock_pthread_mutex_lock_count =
    mock_pthread_mutex_unlock_count =
    mock_pthread_cond_wait_count = 0;
    ok(EINTR == msgq_get(&Q, &Msg), "get returns error on pthread_cond_wait failure");
    ok(Q.head == old_tail, "Head pointer untouched");
    Q.head = old_head;
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q was untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message was untouched");
    ok(1 == mock_pthread_mutex_lock_count, "pthread_mutex_lock was called");
    ok(1 == mock_pthread_cond_wait_count, "pthread_cond_wait_count was called");
    ok(1 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock was called");

    valid_q.queue = pMsg;
    Q = valid_q;
    old_head = Q.head;
    old_tail = Q.tail;
    Q.head = Q.tail;
    memcpy(pMsg, array_m, sizeof(array_m));
    Msg = NullMsg;
    mock_pthread_mutex_lock_failure = 0;
    mock_pthread_cond_wait_failure = EINTR;
    mock_pthread_mutex_unlock_failure = EIO;
    mock_pthread_mutex_lock_count =
    mock_pthread_mutex_unlock_count =
    mock_pthread_cond_wait_count = 0;
    ok(EINTR == msgq_get(&Q, &Msg), "get returns error on pthread_cond_wait failure (not unlock)");
    ok(Q.head == old_tail, "Head pointer untouched");
    Q.head = old_head;
    ok(0 == memcmp(&Q, &valid_q, sizeof(valid_q)), "Q was untouched");
    ok(0 == memcmp(pMsg, array_m, sizeof(array_m)), "queue untouched");
    ok(0 == memcmp(&Msg, &NullMsg, sizeof(NullMsg)), "Message was untouched");
    ok(1 == mock_pthread_mutex_lock_count, "pthread_mutex_lock was called");
    ok(1 == mock_pthread_cond_wait_count, "pthread_cond_wait was called");
    ok(1 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock was called");

    valid_q.queue = pMsg;
    Q = valid_q;
    memcpy(pMsg, array_m, sizeof(array_m));
    Msg = NullMsg;
    mock_pthread_mutex_lock_failure = 0;
    mock_pthread_mutex_lock_count = 0;
    mock_pthread_cond_wait_failure = 0;
    mock_pthread_mutex_unlock_failure = 0;
    mock_pthread_mutex_unlock_count =
    mock_pthread_cond_signal_count =
    mock_pthread_cond_wait_count = 0;
    ok(0 == msgq_get(&Q, &Msg), "get succeeds");
    ok(Q.head == Q.tail, "Pointers updated reasonably");
    ok(0 == memcmp(&Msg, &Req_m, sizeof(Req_m)), "Message was updated");
    ok(1 == mock_pthread_mutex_lock_count, "pthread_mutex_lock was called");
    ok(0 == mock_pthread_cond_wait_count, "pthread_cond_wait_count was called");
    ok(1 == mock_pthread_cond_signal_count, "pthread_cond_signal was called");
    ok(1 == mock_pthread_mutex_unlock_count, "pthread_mutex_unlock was called");

    free(valid_q.queue);
}
static THREAD_FUNC TapeWriteThread(void *dummy)
{
int status;
size_t blen, remain, want, put, nrec;
char *ptr;
OLD_MSGQ_MSG *obuf;
static char *fid = "TapeWriteThread";

    blen = Params->bfact * IDA_BUFSIZ; /* IDA10 OK */
    MUTEX_LOCK(&mp);
        ioerr = 0;
    MUTEX_UNLOCK(&mp);

    while (1) {

        obuf = msgq_get(&Q->obuf, OLD_MSGQ_WAITFOREVER);
        if (!msgq_chkmsg2(fid, obuf)) {
            util_log(1, "%s: corrupt message received", fid);
            ispd_die(MY_MOD_ID + 1);
        }
        nrec = *((size_t *) obuf->data);
        util_log(1, "dumping %ld records to %s", nrec, Params->odev);

        ptr = obuf->data + sizeof(size_t);
        remain = nrec * IDA_BUFSIZ; /* IDA10 OK */

        while (remain > 0) {
            want = remain > blen ? blen : remain;
            nrec = want / IDA_BUFSIZ; /* IDA10 OK */
            do {
                lock_device();
                    put = mtio_write(tp, ptr, want);
                    if (put == want) {
                        MUTEX_LOCK(&Status->lock);
                            Status->output.nrec += nrec;
                            status = Status->output.state;
                        MUTEX_UNLOCK(&Status->lock);
                        ptr += put;
                        if (ioerr) {
                            clear_alarm(ISP_ALARM_IOERR);
                            ioerr = 0;
                        }
                    } else {
                        if (put != 0) {
                            if (++ioerr == 1) {
                                set_alarm(ISP_ALARM_IOERR);
                                util_log(1, "%s: %s",
                                    Params->odev, syserrmsg(errno)
                                );
                            }
                            MUTEX_LOCK(&Status->lock);
                                ++Status->output.err;
                            MUTEX_UNLOCK(&Status->lock);
                            eject_tape(0);
                        }
                    }
                release_device();
                if (put != want) {
                    if (shutting_down()) {
                        complete_shutdown();
                        THREAD_EXIT(0);
                    } else {
                        sleep(5);
                    }
                }
            } while (put != want);
            remain -= put;
        }
        util_log(1, "tape dump completed OK");

        if (shutting_down()) {
            complete_shutdown();
            THREAD_EXIT(0);
        }

        MUTEX_LOCK(&mp);
            if (eject_flag) eject_tape(0);
            eject_flag = 0;
        MUTEX_UNLOCK(&mp);

        msgq_put(&Heap->obuf, obuf);
    }
}
Exemple #9
0
static void
user_result_fd_readable(DCUserConn *uc)
{
    int res;

    res = msgq_read(uc->get_mq);
    if (res == 0 || (res < 0 && errno != EAGAIN)) {
        warn_socket_error(res, false, _("user process %s"), quote(uc->name));
        user_disconnect(uc); /* MSG: socket error above */
        return;
    }
    while (msgq_has_complete_msg(uc->get_mq)) {
        int id;

        msgq_peek(uc->get_mq, MSGQ_INT, &id, MSGQ_END);
        switch (id) {
        case DC_MSG_SCREEN_PUT: {
            char *msg;
            uint32_t flag;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT32, &flag, MSGQ_STR, &msg, MSGQ_END);
            flag_putf((DCDisplayFlag)flag, _("User %s: %s"), quotearg(uc->name), msg); /* msg already quoted */
            free(msg);
            break;
        }
        case DC_MSG_WANT_DOWNLOAD: {
            bool reply;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END);
            reply = !has_user_conn(uc->info, DC_DIR_RECEIVE)
                    && (uc->queue_pos < uc->info->download_queue->cur);
            msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        }
        case DC_MSG_VALIDATE_DIR: {
            DCTransferDirection dir;
            bool reply;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT, &dir, MSGQ_END);
            reply = validate_direction(uc, dir);
            msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        }
        case DC_MSG_VALIDATE_NICK: {
            char *nick;
            bool reply;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_STR, &nick, MSGQ_END);
            reply = validate_nick(uc, nick);
            free(nick);
            if (uc->info != NULL) {
                /* The user can only be DC_ACTIVE_SENT_PASSIVE if we are passive.
                 * So if we managed to connect to them even though we were passive,
                 * they must be active.
                 */
                if (uc->info->active_state == DC_ACTIVE_SENT_PASSIVE)
                    uc->info->active_state = DC_ACTIVE_KNOWN_ACTIVE;
                /* The user can only be DC_ACTIVE_SENT_ACTIVE if we are active.
                 * We must set to DC_ACTIVE_UNKNOWN because otherwise
                 * hub.c:hub_connect_user might say "ConnectToMe already sent to
                 * user" next time we're trying to connect to them.
                 */
                if (uc->info->active_state == DC_ACTIVE_SENT_ACTIVE)
                    uc->info->active_state = DC_ACTIVE_UNKNOWN;
            }
            msgq_put(uc->put_mq, MSGQ_BOOL, reply, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        }
        case DC_MSG_GET_MY_NICK:
            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END);
            msgq_put(uc->put_mq, MSGQ_STR, my_nick, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        case DC_MSG_TRANSFER_STATUS:
            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT64, &uc->transfer_pos, MSGQ_END);
            break;
        case DC_MSG_TRANSFER_START: {
            char *share_filename, *local_filename;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_STR, &local_filename, MSGQ_STR, &share_filename, MSGQ_INT64
                , &uc->transfer_start, MSGQ_INT64, &uc->transfer_total, MSGQ_END);
            if (uc->transfer_start != 0) {
                flag_putf(DC_DF_CONNECTIONS, _("%s: Starting %s of %s (%" PRIu64 " of %" PRIu64 " %s).\n"),
                          quotearg_n(0, uc->info->nick),
                          uc->dir == DC_DIR_SEND ? _("upload") : _("download"),
                          quote_n(1, base_name(share_filename)),
                          uc->transfer_total - uc->transfer_start,
                          uc->transfer_total,
                          ngettext("byte", "bytes", uc->transfer_total));
            } else {
                flag_putf(DC_DF_CONNECTIONS, _("%s: Starting %s of %s (%" PRIu64 " %s).\n"),
                          quotearg_n(0, uc->info->nick),
                          uc->dir == DC_DIR_SEND ? _("upload") : _("download"),
                          quote_n(1, base_name(share_filename)),
                          uc->transfer_total,
                          ngettext("byte", "bytes", uc->transfer_total));
            }
            free(uc->transfer_file);
            uc->transfer_file = share_filename;
            free(uc->local_file);
            uc->local_file = local_filename;
            uc->transferring = true;
            uc->transfer_pos = uc->transfer_start;
            uc->transfer_time = time(NULL);
            if (uc->transfer_time == (time_t) -1)
                warn(_("Cannot get current time - %s\n"), errstr);
            break;
        }
        case DC_MSG_CHECK_DOWNLOAD:
            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END);
            for (; uc->queue_pos < uc->info->download_queue->cur; uc->queue_pos++) {
                DCQueuedFile *queued;
                char *local_file;

                queued = (DCQueuedFile*) uc->info->download_queue->buf[uc->queue_pos];
                if (queued->status != DC_QS_DONE) {
                    local_file = resolve_download_file(uc->info, queued);
                    uc->queued_valid = true;
                    uc->transfer_file = xstrdup(queued->filename);
                    uc->local_file = xstrdup(local_file);
                    uc->occupied_slot = true;
                    queued->status = DC_QS_PROCESSING;
                    used_dl_slots++;
                    msgq_put(uc->put_mq, MSGQ_STR, local_file, MSGQ_STR, uc->transfer_file, MSGQ_INT64, queued->length, MSGQ_INT, queued->flag, MSGQ_END);
                    FD_SET(uc->put_mq->fd, &write_fds);
                    free(local_file);
                    return;
                }
            }
            msgq_put(uc->put_mq, MSGQ_STR, NULL, MSGQ_STR, NULL, MSGQ_INT64, (uint64_t) 0, MSGQ_INT, DC_TF_NORMAL, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        case DC_MSG_DOWNLOAD_ENDED: {
            bool success;
            char *reason;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_BOOL, &success, MSGQ_STR, &reason, MSGQ_END);
            handle_ended_download(uc, success, reason);
            free(reason);
            break;
        }
        case DC_MSG_CHECK_UPLOAD: {
            char *remote_file;
            char *local_file;
            int type;
            uint64_t size = 0;
            DCTransferFlag flag = DC_TF_NORMAL;
            bool permit_transfer = false;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_INT, &type, MSGQ_STR, &remote_file, MSGQ_END);
            local_file = (char*) resolve_upload_file(uc->info, (DCAdcgetType) type, remote_file, &flag, &size);
            free(remote_file);
            uc->transfer_file = NULL;
            if (local_file != NULL) {
                if (flag == DC_TF_LIST || (flag == DC_TF_NORMAL && size <= minislot_size)) {
                    if (used_mini_slots < minislot_count) {
                        used_mini_slots ++;
                        uc->occupied_minislot = true;
                        permit_transfer = true;
                    } else if (used_ul_slots < my_ul_slots || uc->info->slot_granted) {
                        used_ul_slots ++;
                        uc->occupied_slot = true;
                        permit_transfer = true;
                    }
                } else if (flag == DC_TF_NORMAL && size > minislot_size) {
                    if (used_ul_slots < my_ul_slots || uc->info->slot_granted) {
                        used_ul_slots ++;
                        uc->occupied_slot = true;
                        permit_transfer = true;
                    }
                }
                if (permit_transfer) {
                    uc->transfer_file = local_file;
                } else {
                    free(local_file);
                    local_file = NULL;
                }
            } else {
                permit_transfer = true;
            }
            msgq_put(uc->put_mq, MSGQ_BOOL, permit_transfer, MSGQ_STR, local_file, MSGQ_END);
            FD_SET(uc->put_mq->fd, &write_fds);
            break;
        }
        case DC_MSG_UPLOAD_ENDED: {
            bool success;
            char *reason;

            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_BOOL, &success, MSGQ_STR, &reason, MSGQ_END);
            handle_ended_upload(uc, success, reason);
            free(reason);
            break;
        }
        case DC_MSG_TERMINATING:
            /* The TERMINATING message will be sent from users when they're about to
             * shut down properly.
            * XXX: This message may contain the reason it was terminated in the future.
            */
            msgq_get(uc->get_mq, MSGQ_INT, &id, MSGQ_END);
            user_disconnect(uc); /* MSG: reason from DC_MSG_TERMINATING */
            return; /* not break! this is the last message. */
        default:
            warn(_("Received unknown message %d from user process, shutting down process.\n"), id);
            user_disconnect(uc); /* MSG: local communication error? */
            return; /* not break! this is the last message. */
        }
    }
}