- if (write(client->net, INIT_PASSWD, 8) < 0)
- err("Negotiation failed: %m");
- cliserv_magic = htonll(cliserv_magic);
- if (write(client->net, &cliserv_magic, sizeof(cliserv_magic)) < 0)
- err("Negotiation failed: %m");
+ if(!client || !client->modern) {
+ if (write(net, INIT_PASSWD, 8) < 0) {
+ err_nonfatal("Negotiation failed: %m");
+ if(client)
+ exit(EXIT_FAILURE);
+ }
+ cliserv_magic = htonll(cliserv_magic);
+ if (write(net, &cliserv_magic, sizeof(cliserv_magic)) < 0) {
+ err_nonfatal("Negotiation failed: %m");
+ if(client)
+ exit(EXIT_FAILURE);
+ }
+ }
+ if(!client) {
+ uint64_t reserved;
+ uint64_t magic;
+ uint32_t opt;
+ uint64_t namelen;
+ char* name;
+ int i;
+
+ if(!servers)
+ err("programmer error");
+ write(net, &smallflags, sizeof(uint16_t));
+ read(net, &reserved, sizeof(reserved));
+ read(net, &magic, sizeof(magic));
+ magic = ntohll(magic);
+ if(magic != cliserv_magic) {
+ close(net);
+ return NULL;
+ }
+ read(net, &opt, sizeof(opt));
+ opt = ntohl(opt);
+ if(opt != NBD_OPT_EXPORT_NAME) {
+ close(net);
+ return NULL;
+ }
+ read(net, &namelen, sizeof(namelen));
+ namelen = ntohll(namelen);
+ name = malloc(namelen+1);
+ name[namelen+1]=0;
+ read(net, &name, namelen);
+ for(i=0; i<servers->len; i++) {
+ SERVER* serve = &(g_array_index(servers, SERVER, i));
+ if(!strcmp(serve->servename, name)) {
+ CLIENT* client = g_new0(CLIENT, 1);
+ client->server = serve;
+ client->exportsize = OFFT_MAX;
+ client->net = net;
+ client->modern = TRUE;
+ return client;
+ }
+ }
+ }