X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=client_common.c;h=5ac1cdb77ced80efe804c7017d9f4ec7a03bc940;hp=865a1797bd81bbd7e6308278c08249890c1bf241;hb=c59730ef3c559fd79784c55153410db592eebd68;hpb=c41a04fb296e068ebfec78bba9678bf15daea896 diff --git a/client_common.c b/client_common.c index 865a1797..5ac1cdb7 100644 --- a/client_common.c +++ b/client_common.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1997-2011 Andre Noll + * Copyright (C) 1997-2012 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -27,20 +27,41 @@ #define CLIENT_BUFSIZE 4000 /** - * Close the connection to para_server and free all resources. + * Close the connection to para_server and deallocate per-command ressources. * - * \param ct Pointer to the client data. + * \param ct The client task. * - * \sa client_open. + * This frees all ressources of the current command but keeps the configuration + * in \p ct->conf. + * + * \sa \ref client_close(). */ -void client_close(struct client_task *ct) +void client_disconnect(struct client_task *ct) { if (!ct) return; if (ct->scc.fd >= 0) close(ct->scc.fd); sc_free(ct->scc.recv); + ct->scc.recv = NULL; sc_free(ct->scc.send); + ct->scc.send = NULL; + btr_free_node(ct->btrn); + ct->btrn = NULL; +} + +/** + * Close the connection to para_server and free all resources. + * + * \param ct Pointer to the client data. + * + * \sa \ref client_open(), \ref client_disconnect(). + */ +void client_close(struct client_task *ct) +{ + if (!ct) + return; + client_disconnect(ct); free(ct->user); free(ct->config_file); free(ct->key_file); @@ -197,8 +218,7 @@ static void client_post_select(struct sched *s, struct task *t) SESSION_KEY_LEN); hash_to_asc(challenge_hash, buf); PARA_INFO_LOG("--> %s\n", buf); - ret = send_bin_buffer(ct->scc.fd, (char *)challenge_hash, - HASH_SIZE); + ret = write_all(ct->scc.fd, (char *)challenge_hash, HASH_SIZE); if (ret < 0) goto out; ct->status = CL_SENT_CH_RESPONSE; @@ -308,25 +328,43 @@ out: } } -/* connect to para_server and register the client task */ -static int client_connect(struct client_task *ct) +/** + * Connect to para_server and register the client task. + * + * \param ct The initialized client task structure. + * \param s The scheduler instance to register the client task to. + * \param parent The parent node of the client btr node. + * \param child The child node of the client node. + * + * The client task structure given by \a ct must be allocated and initialized + * by \ref client_parse_config() before this function is called. + * + * \return Standard. + */ +int client_connect(struct client_task *ct, struct sched *s, + struct btr_node *parent, struct btr_node *child) { int ret; + PARA_NOTICE_LOG("connecting %s:%d\n", ct->conf.hostname_arg, + ct->conf.server_port_arg); ct->scc.fd = -1; ret = para_connect_simple(IPPROTO_TCP, ct->conf.hostname_arg, ct->conf.server_port_arg); if (ret < 0) return ret; ct->scc.fd = ret; - ct->status = CL_CONNECTED; ret = mark_fd_nonblocking(ct->scc.fd); if (ret < 0) goto err_out; + ct->status = CL_CONNECTED; + ct->btrn = btr_new_node(&(struct btr_node_description) + EMBRACE(.name = "client", .parent = parent, .child = child)); ct->task.pre_select = client_pre_select; ct->task.post_select = client_post_select; + ct->task.error = 0; sprintf(ct->task.status, "client"); - register_task(&ct->task); + register_task(s, &ct->task); return 1; err_out: close(ct->scc.fd); @@ -335,40 +373,36 @@ err_out: } /** - * Open connection to para_server. + * Parse a client configuration. * * \param argc Usual argument count. * \param argv Usual argument vector. - * \param ct_ptr Points to dynamically allocated and initialized client task - * struct upon successful return. + * \param ct_ptr Filled in by this function. * \param loglevel If not \p NULL, the number of the loglevel is stored here. - * \param parent Add the new buffer tree node as a child of this node. - * \param child Add the new buffer tree node as a parent of this node. * - * Check the command line options given by \a argc and argv, set default values - * for user name and rsa key file, read further option from the config file. - * Finally, establish a connection to para_server. + * This checks the command line options given by \a argc and \a argv, sets + * default values for the user name and the name of the rsa key file and reads + * further options from the config file. * - * \return Standard. + * Upon successful return, \a ct_ptr points to a dynamically allocated and + * initialized client task struct. + * + * \return The number of non-option arguments in \a argc/argv on success, + * negative on errors. */ -int client_open(int argc, char *argv[], struct client_task **ct_ptr, - int *loglevel, struct btr_node *parent, struct btr_node *child) +int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr, + int *loglevel) { char *home = para_homedir(); int ret; struct client_task *ct = para_calloc(sizeof(struct client_task)); - ct->btrn = btr_new_node(&(struct btr_node_description) - EMBRACE(.name = "client", .parent = parent, .child = child)); *ct_ptr = ct; ct->scc.fd = -1; ret = -E_CLIENT_SYNTAX; if (client_cmdline_parser(argc, argv, &ct->conf)) goto out; HANDLE_VERSION_FLAG("client", ct->conf); - ret = -E_CLIENT_SYNTAX; - if (!ct->conf.inputs_num) - goto out; ct->config_file = ct->conf.config_file_given? para_strdup(ct->conf.config_file_arg) : @@ -410,17 +444,52 @@ int client_open(int argc, char *argv[], struct client_task **ct_ptr, PARA_INFO_LOG("loglevel: %s\n", ct->conf.loglevel_arg); PARA_INFO_LOG("config_file: %s\n", ct->config_file); PARA_INFO_LOG("key_file: %s\n", ct->key_file); - PARA_NOTICE_LOG("connecting %s:%d\n", ct->conf.hostname_arg, - ct->conf.server_port_arg); - ret = client_connect(ct); + ret = ct->conf.inputs_num; out: free(home); if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - btr_remove_node(ct->btrn); - btr_free_node(ct->btrn); client_close(ct); *ct_ptr = NULL; } return ret; } + +/** + * Parse the client configuration and open a connection to para_server. + * + * \param argc See \ref client_parse_config. + * \param argv See \ref client_parse_config. + * \param ct_ptr See \ref client_parse_config. + * \param loglevel See \ref client_parse_config. + * \param parent See \ref client_connect(). + * \param child See \ref client_connect(). + * \param sched See \ref client_connect(). + * + * This function combines client_parse_config() and client_connect(). It is + * considered a syntax error if no command was given, i.e. if the number + * of non-option arguments is zero. + * + * \return Standard. + */ +int client_open(int argc, char *argv[], struct client_task **ct_ptr, + int *loglevel, struct btr_node *parent, struct btr_node *child, + struct sched *sched) +{ + int ret = client_parse_config(argc, argv, ct_ptr, loglevel); + + if (ret < 0) + return ret; + if (ret == 0) { + ret = -E_CLIENT_SYNTAX; + goto fail; + } + ret = client_connect(*ct_ptr, sched, parent, child); + if (ret < 0) + goto fail; + return 1; +fail: + client_close(*ct_ptr); + *ct_ptr = NULL; + return ret; +}