int main (int argc, char **argv) { char *fname = NULL; char *hostname = NULL; char *progname = argv[0]; int retval = -1; int type = -1; struct tftp_conn *tc; /* Check whether the user wants to put or get a file. */ while (argc > 0) { if (strcmp("-g", argv[0]) == 0) { fname = argv[1]; hostname = argv[2]; type = TFTP_TYPE_GET; break; } else if (strcmp("-p", argv[0]) == 0) { fname = argv[1]; hostname = argv[2]; type = TFTP_TYPE_PUT; break; } argc--; argv++; } /* Print usage message */ if (!fname || !hostname) { fprintf(stderr, "Usage: %s [-g|-p] FILE HOST\n", progname); return -1; } /* Connect to the remote server */ tc = tftp_connect(type, fname, MODE_OCTET, hostname); if (!tc) { fprintf(stderr, "Failed to connect!\n"); return -1; } /* Transfer the file to or from the server */ retval = tftp_transfer(tc); if (retval < 0) { fprintf(stderr, "File transfer failed!\n"); } /* We are done. Cleanup our state. */ tftp_close(tc); return retval; }
int sequence(void) { static int tick = 0, tack = 0; switch (gstate) { case STATE_START: printf("Waiting for DHCP lease...\n"); gstate = STATE_WAIT_NET; break; case STATE_WAIT_NET: if (!(tick & 0xFFFF)) { tick = 0; tack++; } tick++; if (tack == 1000) { tftp = tftp_new(); printf("Timed out...\n"); return 1; } if (eth.dhcp->state == DHCP_BOUND) { gstate = STATE_GOT_NET; } break; case STATE_GOT_NET: printf("Network is up:\n"); printf(" IP address: %d.%d.%d.%d\n", P_IP(eth.ip_addr.addr)); printf(" Netmask: %d.%d.%d.%d\n", P_IP(eth.netmask.addr)); printf(" Gateway: %d.%d.%d.%d\n", P_IP(eth.gw.addr)); printf(" TFTP server: %d.%d.%d.%d\n", P_IP(eth.dhcp->offered_si_addr.addr)); if (eth.dhcp->boot_file_name) printf(" Bootfile: %s\n", eth.dhcp->boot_file_name); else printf(" Bootfile: NONE\n"); #ifdef NETRPC_ENABLE netrpc_init(); #endif #ifdef AUTO_TFTP if (eth.dhcp->offered_si_addr.addr == 0 || !eth.dhcp->boot_file_name) { tftp = tftp_new(); printf("Missing boot settings, falling back to embedded kernel...\n"); return 1; } tftp = tftp_new(); if (!tftp) fatal("tftp alloc failed"); tftp_connect(tftp, ð.dhcp->offered_si_addr, 69); printf("Downloading configuration file...\n"); seq_tftp_get((char*)eth.dhcp->boot_file_name, conf_buf, MAX_KBOOTCONF_SIZE-1, STATE_GOT_CONF); #else gstate = STATE_IDLE; #endif break; case STATE_GOT_CONF: if (t_status != TFTP_STATUS_OK) { printf("Transfer did not complete successfully\n"); printf("Rebooting...\n"); lv1_panic(1); } printf("Configuration: %ld bytes\n", t_recvd); conf_buf[t_recvd] = 0; kbootconf_parse(); if (conf.num_kernels == 0) { printf("No kernels found in configuration file. Rebooting...\n"); lv1_panic(1); } boot_entry = conf.default_idx; printf("Starting to boot '%s'\n", conf.kernels[boot_entry].label); printf("Downloading kernel...\n"); kernel_buf = mm_highmem_freestart(); seq_tftp_get(conf.kernels[boot_entry].kernel, kernel_buf, mm_highmem_freesize(), STATE_GOT_KERNEL); break; case STATE_GOT_KERNEL: if (t_status != TFTP_STATUS_OK) { printf("Transfer did not complete successfully. Rebooting...\n"); lv1_panic(1); } if (kernel_load(kernel_buf, t_recvd) != 0) { printf("Failed to load kernel. Rebooting...\n"); lv1_panic(1); } if (conf.kernels[boot_entry].initrd && conf.kernels[boot_entry].initrd[0]) { printf("Downloading initrd...\n"); initrd_buf = mm_highmem_freestart(); seq_tftp_get(conf.kernels[boot_entry].initrd, initrd_buf, mm_highmem_freesize(), STATE_GOT_INITRD); } else { gstate = STATE_BOOT; } break; case STATE_GOT_INITRD: if (t_status != TFTP_STATUS_OK) { printf("Transfer did not complete successfully. Rebooting...\n"); lv1_panic(1); } mm_highmem_reserve(t_recvd); kernel_set_initrd(initrd_buf, t_recvd); gstate = STATE_BOOT; break; case STATE_BOOT: kernel_build_cmdline(conf.kernels[boot_entry].parameters, conf.kernels[boot_entry].root); shutdown_and_launch(); break; case STATE_WAIT_TFTP: break; case STATE_IDLE: break; } return 0; }