X-Git-Url: http://git.alex.org.uk diff --git a/nbd-server.c b/nbd-server.c index f8028cb..aea5d2f 100644 --- a/nbd-server.c +++ b/nbd-server.c @@ -165,6 +165,10 @@ char pidfname[256]; /**< name of our PID file */ char pidftemplate[256]; /**< template to be used for the filename of the PID file */ char default_authname[] = SYSCONFDIR "/nbd-server/allow"; /**< default name of allow file */ +#define NEG_INIT (1 << 0) +#define NEG_OLD (1 << 1) +#define NEG_MODERN (1 << 2) + int modernsock=0; /**< Socket for the modern handler. Not used if a client was only specified on the command line; only port used if @@ -789,7 +793,9 @@ GArray* parse_cfile(gchar* f, GError** e) { GQuark errdomain; GArray *retval=NULL; gchar **groups; - gboolean value; + gboolean bval; + gint ival; + gchar* sval; gchar* startgroup; gint i; gint j; @@ -823,25 +829,29 @@ GArray* parse_cfile(gchar* f, GError** e) { g_assert(p[j].ptype==PARAM_INT||p[j].ptype==PARAM_STRING||p[j].ptype==PARAM_BOOL); switch(p[j].ptype) { case PARAM_INT: - *((gint*)p[j].target) = - g_key_file_get_integer(cfile, + ival = g_key_file_get_integer(cfile, groups[i], p[j].paramname, &err); + if(!err) { + *((gint*)p[j].target) = ival; + } break; case PARAM_STRING: - *((gchar**)p[j].target) = - g_key_file_get_string(cfile, + sval = g_key_file_get_string(cfile, groups[i], p[j].paramname, &err); + if(!err) { + *((gchar**)p[j].target) = sval; + } break; case PARAM_BOOL: - value = g_key_file_get_boolean(cfile, + bval = g_key_file_get_boolean(cfile, groups[i], p[j].paramname, &err); if(!err) { - if(value) { + if(bval) { *((gint*)p[j].target) |= p[j].flagval; } else { *((gint*)p[j].target) &= ~(p[j].flagval); @@ -849,11 +859,6 @@ GArray* parse_cfile(gchar* f, GError** e) { } break; } - if(!strcmp(p[j].paramname, "port") && !strcmp(p[j].target, modernport)) { - g_set_error(e, errdomain, CFILE_INCORRECT_PORT, "Config file specifies new-style port for oldstyle export"); - g_key_file_free(cfile); - return NULL; - } if(err) { if(err->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND) { if(!p[j].required) { @@ -1361,7 +1366,7 @@ int expflush(CLIENT *client) { * * @param client The client we're negotiating with. **/ -CLIENT* negotiate(int net, CLIENT *client, GArray* servers) { +CLIENT* negotiate(int net, CLIENT *client, GArray* servers, int phase) { char zeros[128]; uint64_t size_host; uint32_t flags = NBD_FLAG_HAS_FLAGS; @@ -1369,14 +1374,14 @@ CLIENT* negotiate(int net, CLIENT *client, GArray* servers) { uint64_t magic; memset(zeros, '\0', sizeof(zeros)); - if(!client || !client->modern) { + if(phase & NEG_INIT) { /* common */ if (write(net, INIT_PASSWD, 8) < 0) { err_nonfatal("Negotiation failed: %m"); if(client) exit(EXIT_FAILURE); } - if(!client || client->modern) { + if(phase & NEG_MODERN) { /* modern */ magic = htonll(opts_magic); } else { @@ -1385,11 +1390,11 @@ CLIENT* negotiate(int net, CLIENT *client, GArray* servers) { } if (write(net, &magic, sizeof(magic)) < 0) { err_nonfatal("Negotiation failed: %m"); - if(client) + if(phase & NEG_OLD) exit(EXIT_FAILURE); } } - if(!client) { + if ((phase & NEG_MODERN) && (phase & NEG_INIT)) { /* modern */ uint32_t reserved; uint32_t opt; @@ -1452,7 +1457,7 @@ CLIENT* negotiate(int net, CLIENT *client, GArray* servers) { flags |= NBD_FLAG_SEND_FUA; if (client->server->flags & F_ROTATIONAL) flags |= NBD_FLAG_ROTATIONAL; - if (!client->modern) { + if (phase & NEG_OLD) { /* oldstyle */ flags = htonl(flags); if (write(client->net, &flags, 4) < 0) @@ -1493,7 +1498,7 @@ int mainloop(CLIENT *client) { #ifdef DODBG int i = 0; #endif - negotiate(client->net, client, NULL); + negotiate(client->net, client, NULL, client->modern ? NEG_MODERN : (NEG_OLD | NEG_INIT)); DEBUG("Entering request loop!\n"); reply.magic = htonl(NBD_REPLY_MAGIC); reply.error = 0; @@ -1932,7 +1937,7 @@ int serveloop(GArray* servers) { if(FD_ISSET(modernsock, &rset)) { if((net=accept(modernsock, (struct sockaddr *) &addrin, &addrinlen)) < 0) err("accept: %m"); - client = negotiate(net, NULL, servers); + client = negotiate(net, NULL, servers, NEG_INIT | NEG_MODERN); if(!client) { err_nonfatal("negotiation failed"); close(net); @@ -2268,6 +2273,7 @@ void glib_message_syslog_redirect(const gchar *log_domain, break; case G_LOG_LEVEL_DEBUG: level=LOG_DEBUG; + break; default: level=LOG_ERR; }