VALUE read_pid(unsigned char **pData) { if(read_1(pData) != ERL_PID) { rb_raise(rb_eStandardError, "Invalid Type, not a pid"); } VALUE node = read_atom(pData); VALUE id = INT2NUM(read_4(pData)); VALUE serial = INT2NUM(read_4(pData)); VALUE creation = INT2FIX(read_1(pData)); VALUE pid_class = rb_const_get(mErlectricity, rb_intern("Pid")); return rb_funcall(pid_class, rb_intern("new"), 4, node, id, serial, creation); }
VALUE read_large_bignum(unsigned char **pData) { if(read_1(pData) != ERL_LARGE_BIGNUM) { rb_raise(rb_eStandardError, "Invalid Type, not a small bignum"); } unsigned int size = read_4(pData); unsigned int sign = read_1(pData); VALUE num = INT2NUM(0); VALUE tmp; unsigned char buf[size + 1]; read_string_raw(buf, pData, size); int i; for(i = 0; i < size; ++i) { tmp = INT2FIX(*(buf + i)); tmp = rb_funcall(tmp, rb_intern("<<"), 1, INT2NUM(i * 8)); num = rb_funcall(num, rb_intern("+"), 1, tmp); } if(sign) { num = rb_funcall(num, rb_intern("*"), 1, INT2NUM(-1)); } return num; }
VALUE read_dict(unsigned char **pData, VALUE forceToEncoding) { int type = read_1(pData); if(!(type == ERL_LIST || type == ERL_NIL)) { rb_raise(rb_eStandardError, "Invalid dict spec, not an erlang list"); } unsigned int length = 0; if(type == ERL_LIST) { length = read_4(pData); } VALUE cHash = rb_const_get(rb_cObject, rb_intern("Hash")); VALUE hash = rb_funcall(cHash, rb_intern("new"), 0); int i; for(i = 0; i < length; ++i) { VALUE pair = read_dict_pair(pData, forceToEncoding); VALUE first = rb_ary_entry(pair, 0); VALUE last = rb_ary_entry(pair, 1); rb_funcall(hash, rb_intern("store"), 2, first, last); } if(type == ERL_LIST) { read_1(pData); } return hash; }
VALUE read_large_tuple(unsigned char **pData, VALUE forceToEncoding) { if(read_1(pData) != ERL_LARGE_TUPLE) { rb_raise(rb_eStandardError, "Invalid Type, not a large tuple"); } unsigned int arity = read_4(pData); return read_tuple(pData, arity, forceToEncoding); }
VALUE read_bin(unsigned char **pData) { if(read_1(pData) != ERL_BIN) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang binary"); } int length = read_4(pData); unsigned char buf[length + 1]; read_string_raw(buf, pData, length); return rb_str_new2((char *) buf); }
VALUE read_bin(unsigned char **pData) { if(read_1(pData) != ERL_BIN) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang binary"); } unsigned int length = read_4(pData); VALUE rStr = rb_str_new((char *) *pData, length); *pData += length; return rStr; }
VALUE read_int(unsigned char **pData) { if(read_1(pData) != ERL_INT) { rb_raise(rb_eStandardError, "Invalid Type, not an int"); } long long value = read_4(pData); long long negative = ((value >> 31) & 0x1 == 1); if(negative) { value = (value - ((long long) 1 << 32)); } return INT2FIX(value); }
VALUE read_large_tuple(unsigned char **pData) { if(read_1(pData) != ERL_LARGE_TUPLE) { rb_raise(rb_eStandardError, "Invalid Type, not a large tuple"); } int arity = read_4(pData); VALUE array = rb_ary_new2(arity); int i; for(i = 0; i < arity; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } return array; }
VALUE read_new_reference(unsigned char **pData) { if(read_1(pData) != ERL_NEW_REF) { rb_raise(rb_eStandardError, "Invalid Type, not a new-style reference"); } int size = read_2(pData); VALUE node = read_atom(pData); VALUE creation = INT2FIX(read_1(pData)); VALUE id = rb_ary_new2(size); int i; for(i = 0; i < size; ++i) { rb_ary_store(id, i, INT2NUM(read_4(pData))); } VALUE newref_class = rb_const_get(mErlectricity, rb_intern("NewReference")); return rb_funcall(newref_class, rb_intern("new"), 3, node, creation, id); }
VALUE read_list(unsigned char **pData) { if(read_1(pData) != ERL_LIST) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang list"); } int size = read_4(pData); VALUE array = rb_ary_new2(size); int i; for(i = 0; i < size; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } read_1(pData); return array; }
VALUE read_list(unsigned char **pData) { if(read_1(pData) != ERL_LIST) { rb_raise(rb_eStandardError, "Invalid Type, not an erlang list"); } unsigned int size = read_4(pData); VALUE newref_class = rb_const_get(mErlectricity, rb_intern("List")); VALUE array = rb_funcall(newref_class, rb_intern("new"), 1, INT2NUM(size)); int i; for(i = 0; i < size; ++i) { rb_ary_store(array, i, read_any_raw(pData)); } read_1(pData); return array; }
static int nvram2env_attach(device_t dev) { struct nvram2env_softc * sc = device_get_softc(dev); struct nvram * nv; char *pair, *value, *assign; uint32_t sig, size, i; if (sc->bst == 0 || sc->addr == 0) return (ENXIO); if (bus_space_map(sc->bst, sc->addr, NVRAM_MAX_SIZE, 0, &sc->bsh) != 0) return (ENXIO); sig = read_4(sc, 0); size = read_4(sc, 4); #if 1 if (bootverbose) device_printf(dev, " size=0x%05x maxsize=0x%05x\n", size, sc->maxsize); #endif size = (size > sc->maxsize)?sc->maxsize:size; if (sig == sc->sig || (sc->flags & NVRAM_FLAGS_UBOOT)) { /* align and shift size to 32bit size*/ size += 3; size >>= 2; nv = malloc(size<<2, M_DEVBUF, M_WAITOK | M_ZERO); if (!nv) return (ENOMEM); for (i = 0; i < size; i ++) ((uint32_t *)nv)[i] = read_4(sc, i<<2); if (sc->flags & NVRAM_FLAGS_BROADCOM) { device_printf(dev, "sig = %#x\n", nv->sig); device_printf(dev, "size = %#x\n", nv->size); } if (!(sc->flags & NVRAM_FLAGS_NOCHECK)) { /* TODO: need checksum verification */ } if (sc->flags & NVRAM_FLAGS_GENERIC) pair = (char*)nv+4; if (sc->flags & NVRAM_FLAGS_UBOOT) pair = (char*)nv+4; else if (sc->flags & NVRAM_FLAGS_BROADCOM) pair = (char*)nv+20; else pair = (char*)nv+4; for ( ; (u_int32_t)pair < ((u_int32_t)nv + size - 4); pair = pair + strlen(pair) + 1 + strlen(value) + 1 ) { if (pair && strlen(pair)) { #if 0 printf("ENV: %s\n", pair); #endif /* hint.nvram.0. */ assign = strchr(pair,'='); assign[0] = '\0'; value = assign+1; #if 1 if (bootverbose) printf("ENV: %s=%s\n", pair, value); #endif setenv(pair, value); if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) { /* Alias for MAC address of eth0 */ if (bootverbose) printf("ENV: aliasing " "WAN_MAC_ADDR to ethaddr" " = %s\n", value); setenv("ethaddr", value); } else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){ /* Alias for MAC address of eth1 */ if (bootverbose) printf("ENV: aliasing " "LAN_MAC_ADDR to eth1addr" " = %s\n", value); setenv("eth1addr", value); } if (strcmp(pair, "bootverbose") == 0) bootverbose = strtoul(value, 0, 0); if (strcmp(pair, "boothowto" ) == 0) boothowto = strtoul(value, 0, 0); } else break; } free(nv, M_DEVBUF); }
int nvram2env_attach(device_t dev) { struct nvram2env_softc *sc; struct nvram *nv; char *pair, *value, *assign; uint32_t sig, size, i, *tmp; sc = device_get_softc(dev); if (sc->bst == 0 || sc->addr == 0) return (ENXIO); if (bus_space_map(sc->bst, sc->addr, NVRAM_MAX_SIZE, 0, &sc->bsh) != 0) return (ENXIO); sig = read_4(sc, 0); size = read_4(sc, 4); if (bootverbose) device_printf(dev, " size=0x%05x maxsize=0x%05x\n", size, sc->maxsize); size = (size > sc->maxsize)?sc->maxsize:size; if (sig == sc->sig || (sc->flags & NVRAM_FLAGS_UBOOT)) { /* align size to 32bit size*/ size += 3; size &= ~3; nv = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO); if (!nv) return (ENOMEM); /* set tmp pointer to begin of NVRAM */ tmp = (uint32_t *) nv; /* use read_4 to swap bytes if it's required */ for (i = 0; i < size; i += 4) { *tmp = read_4(sc, i); tmp++; } /* now tmp pointer is end of NVRAM */ if (sc->flags & NVRAM_FLAGS_BROADCOM) { device_printf(dev, "sig = %#x\n", nv->sig); device_printf(dev, "size = %#x\n", nv->size); } if (!(sc->flags & NVRAM_FLAGS_NOCHECK)) { /* TODO: need checksum verification */ } if (sc->flags & NVRAM_FLAGS_GENERIC) pair = (char*)nv+4; if (sc->flags & NVRAM_FLAGS_UBOOT) pair = (char*)nv+4; else if (sc->flags & NVRAM_FLAGS_BROADCOM) pair = (char*)nv+20; else pair = (char*)nv+4; /* iterate over buffer till end. tmp points to end of NVRAM */ for ( ; pair < (char*)tmp; pair += strlen(pair) + strlen(value) + 2 ) { if (!pair || (strlen(pair) == 0)) break; /* hint.nvram.0. */ assign = strchr(pair,'='); assign[0] = '\0'; value = assign+1; if (bootverbose) printf("ENV[%p]: %s=%s\n", (void*)((char*)pair - (char*)nv), pair, value); kern_setenv(pair, value); if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) { /* Alias for MAC address of eth0 */ if (bootverbose) printf("ENV: aliasing " "WAN_MAC_ADDR to ethaddr" " = %s\n", value); kern_setenv("ethaddr", value); } else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){ /* Alias for MAC address of eth1 */ if (bootverbose) printf("ENV: aliasing " "LAN_MAC_ADDR to eth1addr" " = %s\n", value); kern_setenv("eth1addr", value); } if (strcmp(pair, "bootverbose") == 0) bootverbose = strtoul(value, 0, 0); if (strcmp(pair, "boothowto" ) == 0) boothowto = strtoul(value, 0, 0); } free(nv, M_DEVBUF); } bus_space_unmap(sc->bst, sc->bsh, NVRAM_MAX_SIZE); return (0); }