From: Andre Noll Date: Sat, 17 Aug 2013 11:57:32 +0000 (+0200) Subject: Merge branch 't/remove_sb_compat' X-Git-Tag: v0.5.0~10 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=650e5374914c1eb725ce7d2a720611bec22112bc Merge branch 't/remove_sb_compat' This topic branch was cooking for over 4 months and should now be ready for prime time. The patches break compatibility with earlier versions, so we need to bump the version number real soon now. 72ffa7 client: Only start stdin task for addblob commands. 85a6ae Remove old stream cipher API. d1407f Allow addblob commands to create output. 243e31 client: Remove client_recv_buffer(). 277ed4 client: Remove sb-compatibility code. 36ba18 Reject non-sideband connections. 6ca50b blob: Avoid zero sized memcpy(). cf308c Fix typo in documentation of stdin_command(). fdb9d2 blob: Simplify fd2buf(). --- 650e5374914c1eb725ce7d2a720611bec22112bc diff --cc NEWS index 4127e38b,f323df1d..a1cdf58e --- a/NEWS +++ b/NEWS @@@ -1,30 -1,6 +1,36 @@@ ------------------------------------------- -0.?.? (to be announced) "spectral gravity" ------------------------------------------- +--------------------------------------------- - 0.?.? (to be announced) "invertible validity" ++0.5.0 (to be announced) "invertible validity" +--------------------------------------------- + ++ - The sideband compatibility code has been removed, hence ++ sideband connections (introduced in 0.4.11) are now mandatory. ++ - Addblob commands can produce output. ++ - The stat command no longer sends garbage when para_server was ++ compiled against libgcrypt. ++ +-------------------------------------- +0.4.13 (2013-07-29) "spectral gravity" +-------------------------------------- + +One more 0.4.x release before the API-breaking changes for 0.5.0 go +in. The main features of this release are the ogg/opus audio format, +and UTF-8 support, but it includes also tons of other improvements +and fixes all over the place. + + - New audio format: ogg/opus. + - UTF8 support for para_gui and the mp3 audio format handler. + - Scheduler improvements and fixes. + - The obsolete gettimeofday() function has been replaced + by clock_gettime() on systems which support it. + - Speed and usability improvements for para_gui. + - para_client now restores the fd flags of stdin and stdout + on shutdown. + - Improved manual pages. + - Consistent version strings for all executables. + - Reduced dependencies on generated files result in fewer + recompilations on changes. + - Performance improvements for the compress filter. + - Improved downloads web page. ----------------------------------------- 0.4.12 (2012-12-20) "volatile relativity" diff --cc afs.c index c87fdf78,da92d6c5..49ce13eb --- a/afs.c +++ b/afs.c @@@ -546,31 -546,6 +546,28 @@@ static int activate_mood_or_playlist(ch return 1; } +/** + * Result handler for sending data to the para_client process. + * + * \param result The data to be sent. + * \param band The band designator. + * \param private Pointer to the command context. + * + * \return The return value of the underlying call to \ref command.c::send_sb. + * + * \sa \ref callback_result_handler, \ref command.c::send_sb. + */ +int afs_cb_result_handler(struct osl_object *result, uint8_t band, + void *private) +{ + struct command_context *cc = private; + + assert(cc); + if (!result->size) + return 1; - if (cc->use_sideband) - return send_sb(&cc->scc, result->data, result->size, band, - true); - return sc_send_bin_buffer(&cc->scc, result->data, result->size); ++ return send_sb(&cc->scc, result->data, result->size, band, true); +} + static void com_select_callback(int fd, const struct osl_object *query) { struct para_buffer pb = { diff --cc client.c index 2d6ef31f,44862ab9..873edc16 --- a/client.c +++ b/client.c @@@ -528,26 -531,39 +528,37 @@@ __noreturn static void print_completion #endif /* HAVE_READLINE */ - static int supervisor_post_select(struct sched *s, __a_unused struct task *t) + struct supervisor_task { + bool stdout_task_started; + struct task task; + }; + -static void supervisor_post_select(struct sched *s, struct task *t) ++static int supervisor_post_select(struct sched *s, struct task *t) { + struct supervisor_task *svt = container_of(t, struct supervisor_task, + task); + - if (ct->task.error < 0) { - t->error = ct->task.error; - return; - } + if (ct->task.error < 0) + return ct->task.error; + if (!svt->stdout_task_started && ct->status == CL_EXECUTING) { + stdout_set_defaults(&sot); + register_task(s, &sot.task); + svt->stdout_task_started = true; - return; ++ return 1; + } if (ct->status == CL_SENDING) { stdin_set_defaults(&sit); register_task(s, &sit.task); - t->error = -E_TASK_STARTED; - return; + return -E_TASK_STARTED; } - if (ct->status == CL_RECEIVING) { - stdout_set_defaults(&sot); - register_task(s, &sot.task); - return -E_TASK_STARTED; - } + return 0; } - static struct task svt = { - .post_select = supervisor_post_select, - .status = "supervisor task" + static struct supervisor_task supervisor_task = { + .task = { + .post_select = supervisor_post_select, + .status = "supervisor task" + } }; /** diff --cc client_common.c index 1ecba730,3ff43d1b..c19b7121 --- a/client_common.c +++ b/client_common.c @@@ -326,10 -303,9 +303,9 @@@ static int send_sb_command(struct clien * * \sa struct sched, struct task. */ -static void client_post_select(struct sched *s, struct task *t) +static int client_post_select(struct sched *s, struct task *t) { struct client_task *ct = container_of(t, struct client_task, task); - struct btr_node *btrn = ct->btrn; int ret = 0; size_t n; char buf[CLIENT_BUFSIZE]; @@@ -338,23 -314,24 +314,24 @@@ if (ret < 0) goto out; if (ct->scc.fd < 0) - return; + return 0; switch (ct->status) { case CL_CONNECTED: /* receive welcome message */ - ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); + ret = read_nonblock(ct->scc.fd, buf, sizeof(buf), &s->rfds, &n); if (ret < 0 || n == 0) goto out; ct->features = parse_features(buf); + if (!has_feature("sideband", ct)) { + PARA_ERROR_LOG("server has no sideband support\n"); + ret = -E_INCOMPAT_FEAT; + goto out; + } ct->status = CL_RECEIVED_WELCOME; - return; + return 0; case CL_RECEIVED_WELCOME: /* send auth command */ if (!FD_ISSET(ct->scc.fd, &s->wfds)) - return; + return 0; - if (has_feature("sideband", ct)) { - ct->use_sideband = true; - sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user); - } else - sprintf(buf, AUTH_REQUEST_MSG "%s", ct->user); + sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user); PARA_INFO_LOG("--> %s\n", buf); ret = write_buffer(ct->scc.fd, buf); if (ret < 0) @@@ -406,21 -371,15 +371,15 @@@ hash_to_asc(ct->challenge_hash, buf); PARA_INFO_LOG("--> %s\n", buf); ct->status = CL_RECEIVED_CHALLENGE; - return; + return 0; } case CL_RECEIVED_CHALLENGE: - if (ct->use_sideband) { - ret = send_sb(ct, ct->challenge_hash, HASH_SIZE, - SBD_CHALLENGE_RESPONSE, false); - if (ret != 0) - ct->challenge_hash = NULL; - if (ret <= 0) - goto out; - } else { - ret = write_all(ct->scc.fd, (char *)ct->challenge_hash, HASH_SIZE); - if (ret < 0) - goto out; - } + ret = send_sb(ct, 0, ct->challenge_hash, HASH_SIZE, + SBD_CHALLENGE_RESPONSE, false); + if (ret != 0) + ct->challenge_hash = NULL; + if (ret <= 0) + goto out; ct->status = CL_SENT_CH_RESPONSE; goto out; case CL_SENT_CH_RESPONSE: /* read server response */ @@@ -451,121 -397,78 +397,78 @@@ } case CL_RECEIVED_PROCEED: /* concat args and send command */ { - int i; - char *command = NULL; if (!FD_ISSET(ct->scc.fd, &s->wfds)) - return; + return 0; - if (ct->use_sideband) { - ret = send_sb_command(ct); - if (ret <= 0) - goto out; - ct->status = CL_SENT_COMMAND; - return 0; - } - for (i = 0; i < ct->conf.inputs_num; i++) { - char *tmp = command; - command = make_message("%s\n%s", command? - command : "", ct->conf.inputs[i]); - free(tmp); - } - command = para_strcat(command, EOC_MSG "\n"); - PARA_DEBUG_LOG("--> %s\n", command); - ret = sc_send_buffer(&ct->scc, command); - free(command); - if (ret < 0) + ret = send_sb_command(ct); + if (ret <= 0) goto out; - ct->status = CL_SENT_COMMAND; + ct->status = CL_EXECUTING; - return; + return 0; } - case CL_SENT_COMMAND: - { - char *buf2; - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret <= 0) - goto out; - if (sbb.band == SBD_AWAITING_DATA) { - ct->status = CL_SENDING; - free(sbb.iov.iov_base); - goto out; + case CL_SENDING: + if (ct->btrn[1]) { + char *buf2; + size_t sz; + ret = btr_node_status(ct->btrn[1], 0, BTR_NT_LEAF); + if (ret == -E_BTR_EOF) { + /* empty blob data packet indicates EOF */ + PARA_INFO_LOG("blob sent\n"); + ret = send_sb(ct, 1, NULL, 0, SBD_BLOB_DATA, true); + if (ret >= 0) + ret = -E_BTR_EOF; } - ct->status = CL_RECEIVING; - ret = dispatch_sbb(ct, &sbb); - goto out; - } - /* can not use "buf" here because we need a malloced buffer */ - buf2 = para_malloc(CLIENT_BUFSIZE); - ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); - if (n > 0) { - if (strstr(buf2, AWAITING_DATA_MSG)) { - free(buf2); - ct->status = CL_SENDING; - return 0; + if (ret < 0) + goto close1; + if (ret > 0 && FD_ISSET(ct->scc.fd, &s->wfds)) { + sz = btr_next_buffer(ct->btrn[1], &buf2); + assert(sz); + ret = send_sb(ct, 1, buf2, sz, SBD_BLOB_DATA, true); + if (ret < 0) + goto close1; + if (ret > 0) + btr_consume(ct->btrn[1], sz); } - ct->status = CL_RECEIVING; - btr_add_output(buf2, n, btrn); - } else - free(buf2); - goto out; } - case CL_SENDING: - { - char *buf2; - size_t sz; - ret = btr_node_status(btrn, 0, BTR_NT_LEAF); - if (ret < 0) - goto out; - if (ret == 0) - return 0; - if (!FD_ISSET(ct->scc.fd, &s->wfds)) - return 0; - sz = btr_next_buffer(btrn, &buf2); - ret = sc_send_bin_buffer(&ct->scc, buf2, sz); - if (ret < 0) - goto out; - btr_consume(btrn, sz); - return 0; - } - case CL_RECEIVING: - { - char *buf2; - ret = btr_node_status(btrn, 0, BTR_NT_ROOT); - if (ret < 0) - goto out; - if (ret == 0) - return 0; - /* - * The FD_ISSET() is not strictly necessary, but is allows us - * to skip the malloc below if there is nothing to read anyway. - */ - if (!FD_ISSET(ct->scc.fd, &s->rfds)) - return 0; - if (ct->use_sideband) { - struct sb_buffer sbb; - ret = recv_sb(ct, &s->rfds, &sbb); - if (ret > 0) - ret = dispatch_sbb(ct, &sbb); - goto out; + /* fall though */ + case CL_EXECUTING: + if (ct->btrn[0]) { + ret = btr_node_status(ct->btrn[0], 0, BTR_NT_ROOT); + if (ret < 0) + goto close0; + if (ret > 0 && FD_ISSET(ct->scc.fd, &s->rfds)) { + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret < 0) + goto close0; + if (ret > 0) { + ret = dispatch_sbb(ct, &sbb); + if (ret < 0) + goto close0; + } + } } - buf2 = para_malloc(CLIENT_BUFSIZE); - ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); - if (n > 0) { - buf2 = para_realloc(buf2, n); - btr_add_output(buf2, n, btrn); - } else - free(buf2); + ret = 0; goto out; - } } + close1: + PARA_INFO_LOG("channel 1: %s\n", para_strerror(-ret)); + btr_remove_node(&ct->btrn[1]); + if (ct->btrn[0]) - return; ++ return 0; + goto out; + close0: + PARA_INFO_LOG("channel 0: %s\n", para_strerror(-ret)); + btr_remove_node(&ct->btrn[0]); + if (ct->btrn[1] && ct->status == CL_SENDING) - return; ++ return 0; out: - if (ret < 0) { - if (!ct->use_sideband && ret != -E_SERVER_EOF && - ret != -E_BTR_EOF && ret != -E_EOF) - PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - btr_remove_node(&ct->btrn); - } + if (ret >= 0) - return; ++ return 0; + btr_remove_node(&ct->btrn[0]); + btr_remove_node(&ct->btrn[1]); + if (ret != -E_SERVER_CMD_SUCCESS && ret != -E_SERVER_CMD_FAILURE) + PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - t->error = ret; + return ret; } /** diff --cc command.c index 41a58eac,d4955fb6..4bbf494c --- a/command.c +++ b/command.c @@@ -433,10 -416,10 +417,8 @@@ static int com_version(struct command_c if (cc->argc != 1) return -E_COMMAND_SYNTAX; - msg = VERSION_TEXT("server") "built: " BUILD_DATE "\n" UNAME_RS - ", " CC_VERSION "\n"; - len = strlen(msg); - return send_sb(&cc->scc, msg, len, SBD_OUTPUT, true); + len = xasprintf(&msg, "%s", version_text("server")); - if (cc->use_sideband) - return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false); - return sc_send_bin_buffer(&cc->scc, msg, len); ++ return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false); } #define EMPTY_STATUS_ITEMS \ @@@ -545,15 -527,8 +522,9 @@@ static int com_stat(struct command_cont if (ret < 0) goto out; if (nmmd->vss_status_flags & VSS_NEXT) { + char *esi; ret = empty_status_items(parser_friendly, &esi); - if (cc->use_sideband) - ret = send_sb(&cc->scc, esi, ret, SBD_OUTPUT, - false); - else { - ret = sc_send_bin_buffer(&cc->scc, esi, ret); - free(esi); - } - ret = send_sb(&cc->scc, esi, ret, SBD_OUTPUT, true); ++ ret = send_sb(&cc->scc, esi, ret, SBD_OUTPUT, false); if (ret < 0) goto out; } else diff --cc error.h index ef54ef27,844c0045..51ace983 --- a/error.h +++ b/error.h @@@ -301,8 -289,14 +301,9 @@@ extern const char **para_errlist[] PARA_ERROR(SERVER_EOF, "connection closed by para_server"), \ PARA_ERROR(SERVER_CMD_SUCCESS, "command terminated successfully"), \ PARA_ERROR(SERVER_CMD_FAILURE, "command failed"), \ + PARA_ERROR(INCOMPAT_FEAT, "client/server incompatibility"), \ -#define SCHED_ERRORS \ - PARA_ERROR(NOT_INITIALIZED, "scheduler not yet initialized"), \ - PARA_ERROR(SCHED_SHUTDOWN, "scheduler was shut down"), \ - - #define NET_ERRORS \ PARA_ERROR(NAME_TOO_LONG, "name too long for struct sockaddr_un"), \ PARA_ERROR(ADDRESS_LOOKUP, "can not resolve requested address"),\