ssize_t read_file(unsigned char *buffer, size_t len, const char *path_fmt, ...) { va_list ap; char *path; ssize_t r; int fd; va_start(ap, path_fmt); path = g_strdup_vprintf(path_fmt, ap); va_end(ap); fd = TFR(open(path, O_RDONLY)); g_free(path); if (fd == -1) return -1; r = TFR(read(fd, buffer, len)); TFR(close(fd)); return r; }
ssize_t write_file(const unsigned char *buffer, size_t len, mode_t mode, const char *path_fmt, ...) { va_list ap; char *path; ssize_t r; int fd; va_start(ap, path_fmt); path = g_strdup_vprintf(path_fmt, ap); va_end(ap); if (create_dirs(path, mode | S_IXUSR) != 0) { g_free(path); return -1; } fd = TFR(open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)); if (fd == -1) { g_free(path); return -1; } r = TFR(write(fd, buffer, len)); TFR(close(fd)); if (r != (ssize_t) len) { unlink(path); r = -1; } g_free(path); return r; }
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { int fd; char *dev; struct stat s; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* if no ifname is given, always start the search from tap0. */ int i; char dname[100]; for (i = 0; i < 10; i++) { if (*ifname) { snprintf(dname, sizeof dname, "/dev/%s", ifname); } else { snprintf(dname, sizeof dname, "/dev/tap%d", i); } TFR(fd = open(dname, O_RDWR)); if (fd >= 0) { break; } else if (errno == ENXIO || errno == ENOENT) { break; } if (*ifname) { break; } } if (fd < 0) { error_report("warning: could not open %s (%s): no virtual network emulation", dname, strerror(errno)); return -1; } #else TFR(fd = open("/dev/tap", O_RDWR)); if (fd < 0) { fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); return -1; } #endif fstat(fd, &s); dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); if (*vnet_hdr) { /* BSD doesn't have IFF_VNET_HDR */ *vnet_hdr = 0; if (vnet_hdr_required && !*vnet_hdr) { error_report("vnet_hdr=1 requested, but no kernel " "support for IFF_VNET_HDR available"); close(fd); return -1; } } fcntl(fd, F_SETFL, O_NONBLOCK); return fd; }
static int stats_file_setup(struct stats_file *file) { struct stats_file_header *hdr; struct stat st; size_t size = 0; int err; DBG("file %p fd %d name %s", file, file->fd, file->name); err = fstat(file->fd, &st); if (err < 0) { connman_error("fstat error %s for %s\n", strerror(errno), file->name); TFR(close(file->fd)); g_free(file->name); file->name = NULL; return -errno; } size = (size_t)st.st_size; file->max_len = STATS_MAX_FILE_SIZE; if (size < (size_t)sysconf(_SC_PAGESIZE)) size = sysconf(_SC_PAGESIZE); err = stats_file_remap(file, size); if (err < 0) { TFR(close(file->fd)); g_free(file->name); file->name = NULL; return err; } hdr = get_hdr(file); if (hdr->magic != MAGIC || hdr->begin < sizeof(struct stats_file_header) || hdr->end < sizeof(struct stats_file_header) || hdr->home < sizeof(struct stats_file_header) || hdr->roaming < sizeof(struct stats_file_header) || hdr->begin > file->len || hdr->end > file->len) { hdr->magic = MAGIC; hdr->begin = sizeof(struct stats_file_header); hdr->end = sizeof(struct stats_file_header); hdr->home = UINT_MAX; hdr->roaming = UINT_MAX; stats_file_update_cache(file); } return 0; }
static int net_tap_init(QemuOpts *opts, int *vnet_hdr) { int fd, vnet_hdr_required; char ifname[128] = {0,}; const char *setup_script; if (qemu_opt_get(opts, "ifname")) { pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname")); } *vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1); if (qemu_opt_get(opts, "vnet_hdr")) { vnet_hdr_required = *vnet_hdr; } else { vnet_hdr_required = 0; } TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required)); if (fd < 0) { return -1; } setup_script = qemu_opt_get(opts, "script"); if (setup_script && setup_script[0] != '\0' && strcmp(setup_script, "no") != 0 && launch_script(setup_script, ifname, fd)) { close(fd); return -1; } qemu_opt_set(opts, "ifname", ifname); return fd; }
static void stats_free(gpointer user_data) { struct stats_file *file = user_data; if (!file) return; msync(file->addr, file->len, MS_SYNC); munmap(file->addr, file->len); file->addr = NULL; TFR(close(file->fd)); file->fd = -1; if (file->history_name) { g_free(file->history_name); file->history_name = NULL; } if (file->name) { g_free(file->name); file->name = NULL; } g_free(file); }
static int rtc_start_timer(struct qemu_alarm_timer *t) { int rtc_fd; unsigned long current_rtc_freq = 0; TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY)); if (rtc_fd < 0) return -1; ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); if (current_rtc_freq != RTC_FREQ && ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); goto fail; } if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) { fail: close(rtc_fd); return -1; } enable_sigio_timer(rtc_fd); t->priv = (void *)(long)rtc_fd; return 0; }
static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr, const char *setup_script, char *ifname, size_t ifname_sz, int mq_required) { int fd, vnet_hdr_required; if (tap->has_vnet_hdr) { *vnet_hdr = tap->vnet_hdr; vnet_hdr_required = *vnet_hdr; } else { *vnet_hdr = 1; vnet_hdr_required = 0; } TFR(fd = tap_open(ifname, ifname_sz, vnet_hdr, vnet_hdr_required, mq_required)); if (fd < 0) { return -1; } if (setup_script && setup_script[0] != '\0' && strcmp(setup_script, "no") != 0 && launch_script(setup_script, ifname, fd)) { close(fd); return -1; } return fd; }
static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr, const char *setup_script, char *ifname, size_t ifname_sz, int mq_required, Error **errp) { Error *err = NULL; int fd, vnet_hdr_required; if (tap->has_vnet_hdr) { *vnet_hdr = tap->vnet_hdr; vnet_hdr_required = *vnet_hdr; } else { *vnet_hdr = 1; vnet_hdr_required = 0; } TFR(fd = tap_open(ifname, ifname_sz, vnet_hdr, vnet_hdr_required, mq_required, errp)); if (fd < 0) { return -1; } if (setup_script && setup_script[0] != '\0' && strcmp(setup_script, "no") != 0) { launch_script(setup_script, ifname, fd, &err); if (err) { error_propagate(errp, err); close(fd); return -1; } } return fd; }
static void swap_and_close_files(struct stats_file *history_file, struct stats_file *temp_file) { munmap(history_file->addr, history_file->len); munmap(temp_file->addr, temp_file->len); TFR(close(temp_file->fd)); unlink(history_file->name); if (link(temp_file->name, history_file->name) < 0) return; unlink(temp_file->name); TFR(close(history_file->fd)); }
int qmp_chardev_open_file_source(char *src, int flags, Error **errp) { int fd = -1; TFR(fd = qemu_open(src, flags, 0666)); if (fd == -1) { error_setg_file_open(errp, errno, src); } return fd; }
static int stats_file_close_swap(struct stats_file *history_file, struct stats_file *temp_file) { int err; stats_file_unmap(history_file); stats_file_unmap(temp_file); TFR(close(temp_file->fd)); unlink(history_file->name); err = link(temp_file->name, history_file->name); unlink(temp_file->name); TFR(close(history_file->fd)); stats_file_cleanup(history_file); stats_file_cleanup(temp_file); return err; }
static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt, int64_t pos) { QEMUFileSocket *s = opaque; ssize_t len; ssize_t size = iov_size(iov, iovcnt); ssize_t offset = 0; int err; while (size > 0) { len = iov_send(s->fd, iov, iovcnt, offset, size); if (len > 0) { size -= len; offset += len; } if (size > 0) { err = socket_error(); if (err != EAGAIN && err != EWOULDBLOCK) { error_report("socket_writev_buffer: Got err=%d for (%zu/%zu)", err, (size_t)size, (size_t)len); /* * If I've already sent some but only just got the error, I * could return the amount validly sent so far and wait for the * next call to report the error, but I'd rather flag the error * immediately. */ return -err; } /* Emulate blocking */ GPollFD pfd; pfd.fd = s->fd; pfd.events = G_IO_OUT | G_IO_ERR; pfd.revents = 0; TFR(err = g_poll(&pfd, 1, -1 /* no timeout */)); /* Errors other than EINTR intentionally ignored */ } } return offset; }
static int stats_open(struct stats_file *file, const char *name) { DBG("file %p name %s", file, name); file->name = g_strdup(name); file->fd = TFR(open(file->name, O_RDWR | O_CREAT | O_CLOEXEC, 0644)); if (file->fd < 0) { connman_error("open error %s for %s", strerror(errno), file->name); g_free(file->name); file->name = NULL; return -errno; } return 0; }
static void buffer_fill(const struct ecc_state_s *ecc, uint8_t buffer[], int *len, int *partition, int count, uint8_t jffs_buffer[]) { int ret; switch (*partition) { case 0: if (count < PARTITION_START) { memcpy(buffer, jffs_buffer + count, ecc->style->eccbytes); *len = ecc->style->eccbytes; break; } *partition = 1; case 1: if (count - PARTITION_START < PARTITION_START) { memcpy(buffer, jffs_buffer + count - PARTITION_START, ecc->style->eccbytes); *len = ecc->style->eccbytes; break; } while (*len < ecc->style->eccbytes) { ret = TFR(read(0, buffer + *len, 0x800 - *len)); if (ret <= 0) break; *len += ret; } if (*len == 0) *partition = 2; else if (*len < ecc->style->eccbytes) { fprintf(stderr, "\nWarning: %i stray bytes\n", *len); memset(buffer + *len, 0xff, ecc->style->eccbytes - *len); *len = ecc->style->eccbytes; break; } else break; case 2: memset(buffer, 0xff, ecc->style->eccbytes); *len = ecc->style->eccbytes; break; } }
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { int fd; char *dev; struct stat s; TFR(fd = open("/dev/tap", O_RDWR)); if (fd < 0) { fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); return -1; } fstat(fd, &s); dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); fcntl(fd, F_SETFL, O_NONBLOCK); return fd; }
void os_setup_post(void) { int fd = 0; if (daemonize) { if (chdir("/")) { error_report("not able to chdir to /: %s", strerror(errno)); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) { exit(1); } } change_root(); change_process_uid(); if (daemonize) { uint8_t status = 0; ssize_t len; dup2(fd, 0); dup2(fd, 1); /* In case -D is given do not redirect stderr to /dev/null */ if (!qemu_logfile) { dup2(fd, 2); } close(fd); do { len = write(daemon_pipe, &status, 1); } while (len < 0 && errno == EINTR); if (len != 1) { exit(1); } } }
void os_setup_post(void) { int fd = 0; if (daemonize) { uint8_t status = 0; ssize_t len; again1: len = write(fds[1], &status, 1); LOGV("%s:%s=%d, write(), len = %d", __FILE__, __func__, status, len); if (len == -1 && (errno == EINTR)) goto again1; if (len != 1) exit(1); if (chdir("/")) { perror("not able to chdir to /"); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) exit(1); } change_root(); change_process_uid(); if (daemonize) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } }
static void stats_convert(struct stats_file *file) { struct stats_file temp_file; int err; DBG("converting data file %s", file->name); stats_file_update_cache32(file); bzero(&temp_file, sizeof(struct stats_file)); err = stats_open_temp(&temp_file); if (err < 0) { connman_error("failed to open temporary file during data conversion"); return; } stats_file_setup(&temp_file); struct stats_iter32 data_iter; struct stats_record32 *record; data_iter.file = file; data_iter.begin = get_iterator_begin32(data_iter.file); data_iter.end = get_iterator_end32(data_iter.file); data_iter.it = data_iter.begin; record = get_next_record32(&data_iter); while (record) { struct stats_record *next; if (temp_file.last == get_end(&temp_file)) { err = stats_file_remap(&temp_file, temp_file.len + sysconf(_SC_PAGESIZE)); if (err < 0) { connman_error("failed to extend file %s", temp_file.name); unlink(temp_file.name); stats_file_unmap(&temp_file); TFR(close(temp_file.fd)); stats_file_cleanup(&temp_file); return; } stats_file_update_cache(&temp_file); } next = get_next(&temp_file, get_end(&temp_file)); if (next == get_begin(&temp_file)) { connman_error("ring buffer is full"); unlink(temp_file.name); stats_file_unmap(&temp_file); TFR(close(temp_file.fd)); stats_file_cleanup(&temp_file); return; } next->ts = record->ts; next->roaming = record->roaming; next->data.rx_packets = record->data.rx_packets; next->data.tx_packets = record->data.tx_packets; next->data.rx_bytes = record->data.rx_bytes; next->data.tx_bytes = record->data.tx_bytes; next->data.rx_errors = record->data.rx_errors; next->data.tx_errors = record->data.tx_errors; next->data.rx_dropped = record->data.rx_dropped; next->data.tx_dropped = record->data.tx_dropped; next->data.time = record->data.time; if (next->roaming) set_roaming(&temp_file, next); else set_home(&temp_file, next); set_end(&temp_file, next); record = get_next_record32(&data_iter); } // close and swap stats_file_unmap(file); TFR(close(file->fd)); err = rename(temp_file.name, file->name); if (err < 0) connman_error("failed to rename converted data file %s to %s", temp_file.name, file->name); g_free(temp_file.name); temp_file.name = file->name; memcpy(file, &temp_file, sizeof(struct stats_file)); }
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required, int mq_required) { int fd, s, ret; struct ifreq ifr; TFR(fd = open(PATH_NET_TAP, O_RDWR)); if (fd < 0) { error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno)); return -1; } memset(&ifr, 0, sizeof(ifr)); ret = ioctl(fd, TAPGIFNAME, (void *)&ifr); if (ret < 0) { error_report("could not get tap interface name"); goto error; } if (ifname[0] != '\0') { /* User requested the interface to have a specific name */ s = socket(AF_LOCAL, SOCK_DGRAM, 0); if (s < 0) { error_report("could not open socket to set interface name"); goto error; } ifr.ifr_data = ifname; ret = ioctl(s, SIOCSIFNAME, (void *)&ifr); close(s); if (ret < 0) { error_report("could not set tap interface name"); goto error; } } else { pstrcpy(ifname, ifname_size, ifr.ifr_name); } if (*vnet_hdr) { /* BSD doesn't have IFF_VNET_HDR */ *vnet_hdr = 0; if (vnet_hdr_required && !*vnet_hdr) { error_report("vnet_hdr=1 requested, but no kernel " "support for IFF_VNET_HDR available"); goto error; } } if (mq_required) { error_report("mq_required requested, but not kernel support" "for IFF_MULTI_QUEUE available"); goto error; } fcntl(fd, F_SETFL, O_NONBLOCK); return fd; error: close(fd); return -1; }
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required, int mq_required) { int fd; #ifdef TAPGIFNAME struct ifreq ifr; #else char *dev; struct stat s; #endif /* if no ifname is given, always start the search from tap0/tun0. */ int i; char dname[100]; for (i = 0; i < 10; i++) { if (*ifname) { snprintf(dname, sizeof dname, "/dev/%s", ifname); } else { #if defined(__OpenBSD__) snprintf(dname, sizeof dname, "/dev/tun%d", i); #else snprintf(dname, sizeof dname, "/dev/tap%d", i); #endif } TFR(fd = open(dname, O_RDWR)); if (fd >= 0) { break; } else if (errno == ENXIO || errno == ENOENT) { break; } if (*ifname) { break; } } if (fd < 0) { error_report("warning: could not open %s (%s): no virtual network emulation", dname, strerror(errno)); return -1; } #ifdef TAPGIFNAME if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { fprintf(stderr, "warning: could not get tap name: %s\n", strerror(errno)); return -1; } pstrcpy(ifname, ifname_size, ifr.ifr_name); #else if (fstat(fd, &s) < 0) { fprintf(stderr, "warning: could not stat /dev/tap: no virtual network emulation: %s\n", strerror(errno)); return -1; } dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); #endif if (*vnet_hdr) { /* BSD doesn't have IFF_VNET_HDR */ *vnet_hdr = 0; if (vnet_hdr_required && !*vnet_hdr) { error_report("vnet_hdr=1 requested, but no kernel " "support for IFF_VNET_HDR available"); close(fd); return -1; } } fcntl(fd, F_SETFL, O_NONBLOCK); return fd; }
int main(int argc, char *argv[], char *envp[]) { struct ecc_state_s ecc; uint8_t buffer[0x1000]; int ret, len, count; /* Check if we're called by "flash2raw.spitz" or similar */ len = strlen(argv[0]); if (!strcasecmp(argv[0] + len - 5, "akita")) ecc.style = &akita; else if (!strcasecmp(argv[0] + len - 6, "borzoi")) ecc.style = &borzoi; else if (!strcasecmp(argv[0] + len - 7, "terrier")) ecc.style = &terrier; else ecc.style = &spitz; # ifdef VERBOSE fprintf(stderr, "["); # endif /* Convert data from stdin */ count = 0; while (count < ecc.style->romsize) { len = 0; while (len < ecc.style->page_size) { ret = TFR(read(0, buffer + len, ecc.style->page_size - len)); if (ret <= 0) break; len += ret; } if (len == 0) break; if (len < ecc.style->page_size) { fprintf(stderr, "\nWarning: %i stray bytes\n", len); } TFR(write(1, buffer, ecc.style->page_size)); count += len; len = 0; while (len < ecc.style->oob_size) { ret = TFR(read(0, buffer, ecc.style->oob_size - len)); if (ret <= 0) break; len += ret; } # ifdef VERBOSE if (count * PBAR_LEN / ecc.style->romsize > (count - ecc.style->page_size) * PBAR_LEN / ecc.style->romsize) fprintf(stderr, "#"); # endif } # ifdef VERBOSE fprintf(stderr, "]\n"); # endif return 0; }
static int stats_file_setup(struct stats_file *file) { struct stats_file_header *hdr; struct stat st; size_t size = 0; int err; DBG("file %p fd %d name %s", file, file->fd, file->name); err = fstat(file->fd, &st); if (err < 0) { connman_error("fstat error %s for %s\n", strerror(errno), file->name); TFR(close(file->fd)); g_free(file->name); file->name = NULL; return -errno; } size = (size_t)st.st_size; file->max_len = STATS_MAX_FILE_SIZE; if (size < (size_t)sysconf(_SC_PAGESIZE)) size = sysconf(_SC_PAGESIZE); err = stats_file_remap(file, size); if (err < 0) { TFR(close(file->fd)); g_free(file->name); file->name = NULL; return err; } hdr = get_hdr(file); /* Check if data file is in old format and convert */ if (hdr->magic == MAGIC32 && hdr->begin >= sizeof(struct stats_file_header) && hdr->end >= sizeof(struct stats_file_header) && hdr->home >= sizeof(struct stats_file_header) && hdr->roaming >= sizeof(struct stats_file_header) && hdr->begin <= file->len && hdr->end <= file->len) { stats_convert(file); /* conversion changes the mapped address */ hdr = get_hdr(file); } if (hdr->magic != MAGIC64 || hdr->begin < sizeof(struct stats_file_header) || hdr->end < sizeof(struct stats_file_header) || hdr->home < sizeof(struct stats_file_header) || hdr->roaming < sizeof(struct stats_file_header) || hdr->begin > file->len || hdr->end > file->len) { hdr->magic = MAGIC64; hdr->begin = sizeof(struct stats_file_header); hdr->end = sizeof(struct stats_file_header); hdr->home = UINT_MAX; hdr->roaming = UINT_MAX; stats_file_update_cache(file); } return 0; }
static int stats_open(struct stats_file *file, const char *name) { struct stats_file_header *hdr; struct stat tm; int err; size_t size = 0; bzero(file, sizeof(struct stats_file)); if (name) { file->name = g_strdup(name); file->fd = TFR(open(file->name, O_RDWR | O_CREAT | O_CLOEXEC, 0644)); if (file->fd == -1) { fprintf(stderr, "open error %s for %s\n", strerror(errno), file->name); return -errno; } err = fstat(file->fd, &tm); if (err < 0) { fprintf(stderr, "fstat error %s for %s\n", strerror(errno), file->name); return err; } size = (size_t)tm.st_size; } else { file->name = g_strdup("stats.XXXXXX.tmp"); file->fd = g_mkstemp_full(file->name, O_RDWR | O_CREAT, 0644); if (file->fd == -1) { fprintf(stderr, "creating tmp failed\n"); return -1; } } if (size == 0) size = sysconf(_SC_PAGESIZE); err = stats_file_remap(file, size); if (err < 0) { fprintf(stderr, "remap failed\n"); return err; } /* Initialize new file */ hdr = get_hdr(file); if (hdr->magic != MAGIC || hdr->begin < sizeof(struct stats_file_header) || hdr->end < sizeof(struct stats_file_header) || hdr->home < sizeof(struct stats_file_header) || hdr->roaming < sizeof(struct stats_file_header) || hdr->begin > file->len || hdr->end > file->len) { hdr->magic = MAGIC; hdr->begin = sizeof(struct stats_file_header); hdr->end = sizeof(struct stats_file_header); hdr->home = UINT_MAX; hdr->roaming = UINT_MAX; } stats_file_update_cache(file); return 0; }
/* * Allocate TAP device, returns opened fd. * Stores dev name in the first arg(must be large enough). */ static int tap_alloc(char *dev, size_t dev_size) { int tap_fd, if_fd, ppa = -1; static int ip_fd = 0; char *ptr; static int arp_fd = 0; int ip_muxid, arp_muxid; struct strioctl strioc_if, strioc_ppa; int link_type = I_PLINK;; struct lifreq ifr; char actual_name[32] = ""; memset(&ifr, 0x0, sizeof(ifr)); if( *dev ){ ptr = dev; while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++; ppa = atoi(ptr); } /* Check if IP device was opened */ if( ip_fd ) close(ip_fd); TFR(ip_fd = open("/dev/udp", O_RDWR, 0)); if (ip_fd < 0) { syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)"); return -1; } TFR(tap_fd = open("/dev/tap", O_RDWR, 0)); if (tap_fd < 0) { syslog(LOG_ERR, "Can't open /dev/tap"); return -1; } /* Assign a new PPA and get its unit number. */ strioc_ppa.ic_cmd = TUNNEWPPA; strioc_ppa.ic_timout = 0; strioc_ppa.ic_len = sizeof(ppa); strioc_ppa.ic_dp = (char *)&ppa; if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0) syslog (LOG_ERR, "Can't assign new interface"); TFR(if_fd = open("/dev/tap", O_RDWR, 0)); if (if_fd < 0) { syslog(LOG_ERR, "Can't open /dev/tap (2)"); return -1; } if(ioctl(if_fd, I_PUSH, "ip") < 0){ syslog(LOG_ERR, "Can't push IP module"); return -1; } if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) syslog(LOG_ERR, "Can't get flags\n"); snprintf (actual_name, 32, "tap%d", ppa); pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name); ifr.lifr_ppa = ppa; /* Assign ppa according to the unit number returned by tun device */ if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0) syslog (LOG_ERR, "Can't set PPA %d", ppa); if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0) syslog (LOG_ERR, "Can't get flags\n"); /* Push arp module to if_fd */ if (ioctl (if_fd, I_PUSH, "arp") < 0) syslog (LOG_ERR, "Can't push ARP module (2)"); /* Push arp module to ip_fd */ if (ioctl (ip_fd, I_POP, NULL) < 0) syslog (LOG_ERR, "I_POP failed\n"); if (ioctl (ip_fd, I_PUSH, "arp") < 0) syslog (LOG_ERR, "Can't push ARP module (3)\n"); /* Open arp_fd */ TFR(arp_fd = open ("/dev/tap", O_RDWR, 0)); if (arp_fd < 0) syslog (LOG_ERR, "Can't open %s\n", "/dev/tap"); /* Set ifname to arp */ strioc_if.ic_cmd = SIOCSLIFNAME; strioc_if.ic_timout = 0; strioc_if.ic_len = sizeof(ifr); strioc_if.ic_dp = (char *)𝔦 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){ syslog (LOG_ERR, "Can't set ifname to arp\n"); } if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){ syslog(LOG_ERR, "Can't link TAP device to IP"); return -1; } if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0) syslog (LOG_ERR, "Can't link TAP device to ARP"); close (if_fd); memset(&ifr, 0x0, sizeof(ifr)); pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name); ifr.lifr_ip_muxid = ip_muxid; ifr.lifr_arp_muxid = arp_muxid; if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0) { ioctl (ip_fd, I_PUNLINK , arp_muxid); ioctl (ip_fd, I_PUNLINK, ip_muxid); syslog (LOG_ERR, "Can't set multiplexor id"); } snprintf(dev, dev_size, "tap%d", ppa); return tap_fd; }
int main(int argc, char *argv[], char *envp[]) { struct ecc_state_s ecc; uint8_t buffer[0x1000], ecc_payload[0x40], regs[3], *jffs; int ret, len, eccbyte, count, partition; /* Check if we're called by "raw2flash.spitz" or similar */ len = strlen(argv[0]); if (!strcasecmp(argv[0] + len - 5, "akita")) ecc.style = &akita; else if (!strcasecmp(argv[0] + len - 6, "borzoi")) ecc.style = &borzoi; else if (!strcasecmp(argv[0] + len - 7, "terrier")) ecc.style = &terrier; else ecc.style = &spitz; # ifdef VERBOSE fprintf(stderr, "["); # endif /* Skip first 10 bytes */ TFR(read(0, buffer, 0x10)); len = 0; jffs = (uint8_t *) malloc(PARTITION_START); while (len < PARTITION_START) { ret = TFR(read(0, jffs + len, PARTITION_START - len)); if (ret <= 0) break; len += ret; } /* Convert data from stdin */ partition = len = eccbyte = count = 0; memset(ecc_payload, 0xff, ecc.style->oob_size); jffs2_format(&ecc, ecc_payload); while (count < ecc.style->romsize) { buffer_fill(&ecc, buffer, &len, &partition, count, jffs); buffer_digest(&ecc, buffer, regs); ecc_payload[ecc.style->eccpos[eccbyte ++]] = regs[0]; ecc_payload[ecc.style->eccpos[eccbyte ++]] = regs[1]; ecc_payload[ecc.style->eccpos[eccbyte ++]] = regs[2]; TFR(write(1, buffer, ecc.style->eccbytes)); count += ecc.style->eccbytes; len -= ecc.style->eccbytes; memmove(buffer, buffer + ecc.style->eccbytes, len); if (eccbyte >= ecc.style->eccsize) { TFR(write(1, ecc_payload, ecc.style->oob_size)); eccbyte = 0; memset(ecc_payload, 0xff, ecc.style->oob_size); if (partition < 2) jffs2_format(&ecc, ecc_payload); } # ifdef VERBOSE if (count * PBAR_LEN / ecc.style->romsize > (count - ecc.style->eccbytes) * PBAR_LEN / ecc.style->romsize) fprintf(stderr, "#"); # endif } # ifdef VERBOSE fprintf(stderr, "]\n"); # endif free(jffs); return 0; }