/** * Instantiate a downloader * * @v job Job control interface * @v image Image to fill with downloaded file * @v type Location type to pass to xfer_open() * @v ... Remaining arguments to pass to xfer_open() * @ret rc Return status code * * Instantiates a downloader object to download the specified URI into * the specified image object. */ int create_downloader ( struct interface *job, struct image *image, int type, ... ) { struct downloader *downloader; va_list args; int rc; /* Allocate and initialise structure */ downloader = zalloc ( sizeof ( *downloader ) ); if ( ! downloader ) return -ENOMEM; ref_init ( &downloader->refcnt, downloader_free ); intf_init ( &downloader->job, &downloader_job_desc, &downloader->refcnt ); intf_init ( &downloader->xfer, &downloader_xfer_desc, &downloader->refcnt ); downloader->image = image_get ( image ); va_start ( args, type ); /* Instantiate child objects and attach to our interfaces */ if ( ( rc = xfer_vopen ( &downloader->xfer, type, args ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ intf_plug_plug ( &downloader->job, job ); ref_put ( &downloader->refcnt ); va_end ( args ); return 0; err: downloader_finished ( downloader, rc ); ref_put ( &downloader->refcnt ); va_end ( args ); return rc; }
static int numeric_resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct numeric_resolv *numeric; struct sockaddr_in *sin; /* Allocate and initialise structure */ numeric = zalloc ( sizeof ( *numeric ) ); if ( ! numeric ) return -ENOMEM; ref_init ( &numeric->refcnt, NULL ); intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt ); process_init ( &numeric->process, &numeric_process_desc, &numeric->refcnt ); memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); DBGC ( numeric, "NUMERIC %p attempting to resolve \"%s\"\n", numeric, name ); /* Attempt to resolve name */ sin = ( ( struct sockaddr_in * ) &numeric->sa ); if ( inet_aton ( name, &sin->sin_addr ) != 0 ) { sin->sin_family = AF_INET; } else { numeric->rc = -EINVAL; } /* Attach to parent interface, mortalise self, and return */ intf_plug_plug ( &numeric->resolv, resolv ); ref_put ( &numeric->refcnt ); return 0; }
/** * Create ELS response * * @v xchg Exchange interface * @v port Fibre Channel port * @v port_id Local port ID * @v peer_port_id Peer port ID * @ret rc Return status code */ static int fc_els_respond ( struct interface *xchg, struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id ) { struct fc_els *els; /* Allocate and initialise structure */ els = fc_els_create ( port, port_id, peer_port_id ); if ( ! els ) return -ENOMEM; /* Attach to exchange interface, mortalise self, and return */ intf_plug_plug ( &els->xchg, xchg ); ref_put ( &els->refcnt ); return 0; }
/** * Create ELS request * * @v job Parent job-control interface * @v port Fibre Channel port * @v peer_port_id Peer port ID * @v handler ELS handler * @ret rc Return status code */ int fc_els_request ( struct interface *job, struct fc_port *port, struct fc_port_id *peer_port_id, struct fc_els_handler *handler ) { struct fc_els *els; /* Allocate and initialise structure */ els = fc_els_create ( port, &port->port_id, peer_port_id ); if ( ! els ) return -ENOMEM; els->handler = handler; els->flags = FC_ELS_REQUEST; process_add ( &els->process ); /* Attach to parent job interface, mortalise self, and return */ intf_plug_plug ( &els->job, job ); ref_put ( &els->refcnt ); return 0; }
static int numeric_resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct numeric_resolv *numeric; /* Allocate and initialise structure */ numeric = zalloc ( sizeof ( *numeric ) ); if ( ! numeric ) return -ENOMEM; ref_init ( &numeric->refcnt, NULL ); intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt ); process_init ( &numeric->process, &numeric_process_desc, &numeric->refcnt ); memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) ); /* Attempt to resolve name */ numeric->rc = sock_aton ( name, &numeric->sa ); /* Attach to parent interface, mortalise self, and return */ intf_plug_plug ( &numeric->resolv, resolv ); ref_put ( &numeric->refcnt ); return 0; }
/** * Start name resolution * * @v resolv Name resolution interface * @v name Name to resolve * @v sa Socket address to complete * @ret rc Return status code */ int resolv ( struct interface *resolv, const char *name, struct sockaddr *sa ) { struct resolv_mux *mux; size_t name_len = ( strlen ( name ) + 1 ); int rc; /* Allocate and initialise structure */ mux = zalloc ( sizeof ( *mux ) + name_len ); if ( ! mux ) return -ENOMEM; ref_init ( &mux->refcnt, NULL ); intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt ); intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt ); mux->resolver = table_start ( RESOLVERS ); if ( sa ) memcpy ( &mux->sa, sa, sizeof ( mux->sa ) ); memcpy ( mux->name, name, name_len ); DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name ); /* Start first resolver in chain. There will always be at * least one resolver (the numeric resolver), so no need to * check for the zero-resolvers-available case. */ if ( ( rc = resmux_try ( mux ) ) != 0 ) goto err; /* Attach parent interface, mortalise self, and return */ intf_plug_plug ( &mux->parent, resolv ); ref_put ( &mux->refcnt ); return 0; err: ref_put ( &mux->refcnt ); return rc; }