int tftp_open(char *path, struct open_file *f) { struct tftp_handle *tftpfile; struct iodesc *io; int res; tftpfile = (struct tftp_handle *) alloc(sizeof(*tftpfile)); if (tftpfile == NULL) return ENOMEM; tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata)); io->destip = servip; tftpfile->off = 0; tftpfile->path = path; /* XXXXXXX we hope it's static */ res = tftp_makereq(tftpfile); if (res) { free(tftpfile, sizeof(*tftpfile)); return res; } f->f_fsdata = (void *) tftpfile; return 0; }
static int tftp_open(const char *path, struct open_file *f) { struct tftp_handle *tftpfile; struct iodesc *io; int res; if (strcmp(f->f_dev->dv_name, "net") != 0) { #ifdef __i386__ if (strcmp(f->f_dev->dv_name, "pxe") != 0) return (EINVAL); #else return (EINVAL); #endif } if (is_open) return (EBUSY); tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile)); if (!tftpfile) return (ENOMEM); memset(tftpfile, 0, sizeof(*tftpfile)); tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE; tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata)); if (io == NULL) return (EINVAL); io->destip = servip; tftpfile->off = 0; tftpfile->path = strdup(path); if (tftpfile->path == NULL) { free(tftpfile); return(ENOMEM); } res = tftp_makereq(tftpfile); if (res) { free(tftpfile->path); free(tftpfile); return (res); } f->f_fsdata = (void *) tftpfile; is_open = 1; return (0); }
static int tftp_open(const char *path, struct open_file *f) { struct tftp_handle *tftpfile; struct iodesc *io; int res; /* Avoid trying out tftp_open for disk devices in the EFI loader */ #ifndef __i386__ if (strcmp(f->f_dev->dv_name, "net") != 0) return (EINVAL); #endif tftpfile = (struct tftp_handle *) malloc(sizeof(*tftpfile)); if (!tftpfile) return (ENOMEM); tftpfile->iodesc = io = socktodesc(*(int *) (f->f_devdata)); if (io == NULL) { free(tftpfile); return (EINVAL); } io->destip = servip; tftpfile->off = 0; tftpfile->path = strdup(path); if (tftpfile->path == NULL) { free(tftpfile); return(ENOMEM); } res = tftp_makereq(tftpfile); if (res) { free(tftpfile->path); free(tftpfile); return (res); } f->f_fsdata = (void *) tftpfile; return (0); }
static int tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid /* out */) { struct tftp_handle *tftpfile; static int tc = 0; tftpfile = (struct tftp_handle *) f->f_fsdata; while (size > 0) { int needblock, count; if (!(tc++ % 16)) twiddle(); needblock = tftpfile->off / tftpfile->tftp_blksize + 1; if (tftpfile->currblock > needblock) { /* seek backwards */ tftp_senderr(tftpfile, 0, "No error: read aborted"); tftp_makereq(tftpfile); /* no error check, it worked * for open */ } while (tftpfile->currblock < needblock) { int res; res = tftp_getnextblock(tftpfile); if (res) { /* no answer */ #ifdef TFTP_DEBUG printf("tftp: read error\n"); #endif return (res); } if (tftpfile->islastblock) break; } if (tftpfile->currblock == needblock) { int offinblock, inbuffer; offinblock = tftpfile->off % tftpfile->tftp_blksize; inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { #ifdef TFTP_DEBUG printf("tftp: invalid offset %d\n", tftpfile->off); #endif return (EINVAL); } count = (size < inbuffer ? size : inbuffer); bcopy(tftpfile->lastdata.t.th_data + offinblock, addr, count); addr = (char *)addr + count; tftpfile->off += count; size -= count; if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ } else { #ifdef TFTP_DEBUG printf("tftp: block %d not found\n", needblock); #endif return (EINVAL); } } if (resid) *resid = size; return (0); }
int tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid) { struct tftp_handle *tftpfile; #if !defined(LIBSA_NO_TWIDDLE) static int tc = 0; #endif tftpfile = (struct tftp_handle *) f->f_fsdata; while (size > 0) { int needblock; size_t count; needblock = tftpfile->off / SEGSIZE + 1; if (tftpfile->currblock > needblock) { /* seek backwards */ #ifndef TFTP_NOTERMINATE tftp_terminate(tftpfile); #endif /* Don't bother to check retval: it worked for open() */ tftp_makereq(tftpfile); } while (tftpfile->currblock < needblock) { int res; #if !defined(LIBSA_NO_TWIDDLE) if ((tc++ % 16) == 0) twiddle(); #endif res = tftp_getnextblock(tftpfile); if (res) { /* no answer */ #ifdef DEBUG printf("tftp: read error (block %d->%d)\n", tftpfile->currblock, needblock); #endif return res; } if (tftpfile->islastblock) break; } if (tftpfile->currblock == needblock) { size_t offinblock, inbuffer; offinblock = tftpfile->off % SEGSIZE; inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { #ifdef DEBUG printf("tftp: invalid offset %d\n", tftpfile->off); #endif return EINVAL; } count = (size < inbuffer ? size : inbuffer); bcopy(tftpfile->lastdata.t.th_data + offinblock, addr, count); addr = (caddr_t)addr + count; tftpfile->off += count; size -= count; if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ } else { #ifdef DEBUG printf("tftp: block %d not found\n", needblock); #endif return EINVAL; } } if (resid != NULL) *resid = size; return 0; }