static nvram_handle_t * nvram_open_staging(void) { if( nvram_find_staging() != NULL || nvram_to_staging() == 0 ) return nvram_open(NVRAM_STAGING, NVRAM_RW); return NULL; }
int env_save(void) { int size; unsigned char *buffer; unsigned char *buffer_end; unsigned char *ptr; queue_t *qb; cfe_envvar_t *env; int namelen; int valuelen; int flg; flg = nvram_open(); if (flg < 0) return flg; nvram_erase(); size = nvram_getsize(); buffer = KMALLOC(size,0); if (buffer == NULL) return CFE_ERR_NOMEM; buffer_end = buffer + size; ptr = buffer; for (qb = env_envvars.q_next; qb != &env_envvars; qb = qb->q_next) { env = (cfe_envvar_t *) qb; if (env->flags & (ENV_FLG_BUILTIN)) continue; namelen = strlen(env->name); valuelen = strlen(env->value); if ((ptr + 2 + namelen + valuelen + 1 + 1 + 1) > buffer_end) break; *ptr++ = ENV_TLV_TYPE_ENV; /* TLV record type */ *ptr++ = (namelen + valuelen + 1 + 1); /* TLV record length */ *ptr++ = (unsigned char)env->flags; memcpy(ptr,env->name,namelen); /* TLV record data */ ptr += namelen; *ptr++ = '='; memcpy(ptr,env->value,valuelen); ptr += valuelen; } *ptr++ = ENV_TLV_TYPE_END; size = nvram_write(buffer,0,ptr-buffer); KFREE(buffer); nvram_close(); return (size == (ptr-buffer)) ? 0 : CFE_ERR_IOERR; }
static nvram_handle_t * nvram_open_rdonly(void) { const char *file = nvram_find_staging(); if( file == NULL ) file = nvram_find_mtd(); if( file != NULL ) return nvram_open(file, NVRAM_RO); return NULL; }
int env_load(void) { int size; unsigned char *buffer; unsigned char *ptr; unsigned char *envval; unsigned int reclen; unsigned int rectype; int offset; int flg; int retval = -1; char valuestr[256]; /* * If in 'safe mode', don't read the environment the first time. */ if (cfe_startflags & CFE_INIT_SAFE) { cfe_startflags &= ~CFE_INIT_SAFE; return 0; } flg = nvram_open(); if (flg < 0) return flg; size = nvram_getsize(); buffer = KMALLOC(size,0); if (buffer == NULL) return CFE_ERR_NOMEM; ptr = buffer; offset = 0; /* Read the record type and length */ if (nvram_read(ptr,offset,1) != 1) { retval = CFE_ERR_IOERR; goto error; } while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { /* Adjust pointer for TLV type */ rectype = *(ptr); offset++; size--; /* * Read the length. It can be either 1 or 2 bytes * depending on the code */ if (rectype & ENV_LENGTH_8BITS) { /* Read the record type and length - 8 bits */ if (nvram_read(ptr,offset,1) != 1) { retval = CFE_ERR_IOERR; goto error; } reclen = *(ptr); size--; offset++; } else { /* Read the record type and length - 16 bits, MSB first */ if (nvram_read(ptr,offset,2) != 2) { retval = CFE_ERR_IOERR; goto error; } reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); size -= 2; offset += 2; } if (reclen > size) break; /* should not happen, bad NVRAM */ switch (rectype) { case ENV_TLV_TYPE_ENV: /* Read the TLV data */ if (nvram_read(ptr,offset,reclen) != reclen) goto error; flg = *ptr++; envval = (unsigned char *) strnchr(ptr,'=',(reclen-1)); if (envval) { *envval++ = '\0'; memcpy(valuestr,envval,(reclen-1)-(envval-ptr)); valuestr[(reclen-1)-(envval-ptr)] = '\0'; env_setenv(ptr,valuestr,flg); } break; default: /* Unknown TLV type, skip it. */ break; } /* * Advance to next TLV */ size -= (int)reclen; offset += reclen; /* Read the next record type */ ptr = buffer; if (nvram_read(ptr,offset,1) != 1) goto error; } retval = 0; /* success! */ error: KFREE(buffer); nvram_close(); return retval; }
/* * nvram_main() * Endless loop to receive and serve requests */ static void nvram_main() { struct msg msg; int x; struct file *f; loop: /* * Receive a message, log an error and then keep going */ x = msg_receive(nvram_port, &msg); if (x < 0) { syslog(LOG_ERR, "msg_receive"); goto loop; } /* * All incoming data should fit in one buffer */ if (msg.m_nseg > 1) { msg_err(msg.m_sender, EINVAL); goto loop; } /* * Categorize by basic message operation */ f = hash_lookup(filehash, msg.m_sender); msg.m_op &= MSG_MASK; switch (msg.m_op) { case M_CONNECT: /* New client */ nvram_new_client(&msg); break; case M_DISCONNECT: /* Client done */ nvram_dead_client(&msg, f); break; case M_DUP: /* File handle dup during exec() */ nvram_dup_client(&msg, f); break; case M_ABORT: /* Aborted operation */ /* * We're synchronous, so presumably the operation is * done and this abort is old news */ msg_reply(msg.m_sender, &msg); break; case FS_SEEK: /* Set position */ if (!f || (msg.m_arg < 0)) { msg_err(msg.m_sender, EINVAL); break; } f->f_pos = msg.m_arg; msg.m_arg = msg.m_arg1 = msg.m_nseg = 0; msg_reply(msg.m_sender, &msg); break; case FS_ABSREAD: /* Set position, then read */ case FS_ABSWRITE: /* Set position, then write */ if (!f || (msg.m_arg1 < 0)) { msg_err(msg.m_sender, EINVAL); break; } f->f_pos = msg.m_arg1; msg.m_op = (msg.m_op == FS_ABSREAD) ? FS_READ : FS_WRITE; /* * Now fall into FS_READ/FS_WRITE */ case FS_READ: /* Read file */ case FS_WRITE: /* Write file */ if (nvram_check_gen(&msg, f)) { break; } nvram_readwrite(&msg, f); break; case FS_STAT: /* Get stat of file */ if (nvram_check_gen(&msg, f)) { break; } nvram_stat(&msg, f); break; case FS_WSTAT: /* Writes stats */ if (nvram_check_gen(&msg, f)) { break; } nvram_wstat(&msg, f); break; case FS_OPEN: /* Move from dir down into drive */ if (!valid_fname(msg.m_buf, x)) { msg_err(msg.m_sender, EINVAL); break; } nvram_open(&msg, f); break; default: /* Unknown */ msg_err(msg.m_sender, EINVAL); break; } goto loop; }