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
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 #3
0
void * writer_start(void * usr)
{
    uint32_t msg[2] = {WORK, 10};
    while(1)
    {
        msgq_put(replyq, msg, sizeof(msg));
    }
    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 #5
0
DCLookup *
add_lookup_request(const char *node, const char *service, const struct addrinfo *hints, DCLookupCallback callback, void *userdata)
{
    void *data;
    size_t size;
    DCLookup *lookup;

    addrinfo_to_data(hints, &data, &size);
    msgq_put(lookup_request_mq, MSGQ_STR, node, MSGQ_STR, service, MSGQ_BLOB, data, size, MSGQ_END);
    free(data);
    FD_SET(lookup_request_mq->fd, &write_fds);

    lookup = (DCLookup*) xmalloc(sizeof(DCLookup));
    lookup->callback = callback;
    lookup->data = userdata;
    lookup->cancelled = false;
    ptrv_append(pending_lookups, lookup);

    return lookup;
}
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 #7
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. */
        }
    }
}