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; } } }
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); } }
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); }
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++; } } }
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); }
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); } }
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. */ } } }