static void doit (void) { struct taia stamp; struct taia deadline; int j = 0, r = 0, iolen = 0; for (;;) { taia_now (&stamp); taia_uint (&deadline, 120); taia_add (&deadline, &deadline, &stamp); iolen = 0; udp53io = io + iolen++; udp53io->fd = udp53; udp53io->events = IOPAUSE_READ; tcp53io = io + iolen++; tcp53io->fd = tcp53; tcp53io->events = IOPAUSE_READ; for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { u[j].io = io + iolen++; query_io (&u[j].q, u[j].io, &deadline); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { t[j].io = io + iolen++; if (t[j].state == 0) query_io (&t[j].q, t[j].io, &deadline); else { if (taia_less (&t[j].timeout, &deadline)) deadline = t[j].timeout; t[j].io->fd = t[j].tcp; t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE; } } } iopause (io, iolen, &deadline, &stamp); for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { r = query_get (&u[j].q, u[j].io, &stamp); if (r == -1) u_drop (j); if (r == 1) u_respond (j); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { if (t[j].io->revents) t_timeout (j); if (t[j].state == 0) { r = query_get (&t[j].q, t[j].io, &stamp); if (r == -1) t_drop (j); if (r == 1) t_respond (j); } else if (t[j].io->revents || taia_less (&t[j].timeout, &stamp)) t_rw (j); } } if (udp53io && udp53io->revents) u_new(); if (tcp53io && tcp53io->revents) t_new(); } }
static int parse (const char *arg, char **path_ret, char **protocol_ret, char ***server_ret, char **username_ret, char **password_ret) { CLEANUP_XMLFREEURI xmlURIPtr uri = NULL; CLEANUP_FREE char *socket = NULL; char *path; uri = xmlParseURI (arg); if (!uri) { fprintf (stderr, _("%s: --add: could not parse URI '%s'\n"), getprogname (), arg); return -1; } /* Note we don't do much checking of the parsed URI, since the * underlying function 'guestfs_add_drive_opts' will check for us. * So just the basics here. */ if (uri->scheme == NULL || STREQ (uri->scheme, "")) { /* Probably can never happen. */ fprintf (stderr, _("%s: %s: scheme of URI is NULL or empty\n"), getprogname (), arg); return -1; } socket = query_get (uri, "socket"); if (uri->server && STRNEQ (uri->server, "") && socket) { fprintf (stderr, _("%s: %s: cannot both a server name and a socket query parameter\n"), getprogname (), arg); return -1; } /* Is this needed? XXX if (socket && socket[0] != '/') { fprintf (stderr, _("%s: --add %s: socket query parameter must be an absolute path\n"), getprogname (), arg); return -1; } */ *protocol_ret = strdup (uri->scheme); if (*protocol_ret == NULL) { perror ("strdup: protocol"); return -1; } if (make_server (uri, socket, server_ret) == -1) { free (*protocol_ret); return -1; } *password_ret = NULL; *username_ret = NULL; if (uri->user && STRNEQ (uri->user, "")) { char *p = strchr (uri->user, ':'); if (p != NULL) { if (STRNEQ (p+1, "")) { *password_ret = strdup (p+1); if (*password_ret == NULL) { perror ("strdup: password"); free (*protocol_ret); guestfs_int_free_string_list (*server_ret); return -1; } } *p = '\0'; } *username_ret = strdup (uri->user); if (*username_ret == NULL) { perror ("strdup: username"); free (*password_ret); free (*protocol_ret); guestfs_int_free_string_list (*server_ret); return -1; } } /* We may have to adjust the path depending on the protocol. For * example ceph/rbd URIs look like rbd:///pool/disk, but the * exportname expected will be "pool/disk". Here, uri->path will be * "/pool/disk" so we have to knock off the leading '/' character. */ path = uri->path; if (path && path[0] == '/' && (STREQ (uri->scheme, "gluster") || STREQ (uri->scheme, "iscsi") || STREQ (uri->scheme, "rbd") || STREQ (uri->scheme, "sheepdog"))) path++; *path_ret = strdup (path ? path : ""); if (*path_ret == NULL) { perror ("strdup: path"); free (*protocol_ret); guestfs_int_free_string_list (*server_ret); free (*username_ret); free (*password_ret); return -1; } return 0; }