#include "global.h" #include "ub_env.h" env_t *env; static int ub_flash_io(const char *csSec, int mode) { int f, l, rlen; const char *str; size_t siz; ait_val_t v; FTRACE(4); str = cfg_getAttribute(&cfg, csSec, "size"); siz = strtol(str, NULL, 0); if (!siz) return -1; str = cfg_getAttribute(&cfg, csSec, "drive"); if (!str) { printf("Error:: drive not found!\n"); return -1; } cfg_loadAttribute(&cfg, "ube", "lock", &v, UBE_LOCK); l = open(AIT_GET_STR(&v), O_CREAT | O_EXCL | O_WRONLY, 0644); if (l == -1) { printf("Error:: Locked u-boot-env map %s\n", AIT_GET_STR(&v)); AIT_FREE_VAL(&v); return -1; } f = open(str, mode); if (f == -1) { printf("Error:: Can't access u-boot-env device %s\n", str); close(l); unlink(AIT_GET_STR(&v)); AIT_FREE_VAL(&v); return -1; } if (mode & O_RDWR) { rlen = write(f, env, siz); if (rlen != siz) printf("Error:: written %d bytes != %d\n", rlen, siz); else VERB(3) printf("Written %d bytes\n", rlen); lseek(f, 0, SEEK_SET); } rlen = read(f, env, siz); if (rlen != siz) printf("Error:: readed %d bytes != %d\n", rlen, siz); else VERB(3) printf("Readed %d bytes\n", rlen); close(f); close(l); unlink(AIT_GET_STR(&v)); AIT_FREE_VAL(&v); return 0; } static inline const char * ub_envmatch(const char *csName, const char *e) { while (*csName == *e++) if (*csName++ == '=') return e; if (!*csName && *(e - 1) == '=') return e; return NULL; } int ub_load(const char *csSec) { const char *str; size_t siz; FTRACE(4); str = cfg_getAttribute(&cfg, csSec, "size"); siz = strtol(str, NULL, 0); if (!siz) return -1; env = e_malloc(siz); if (!env) { ELIBERR(elwix); return -1; } return ub_flash_io(csSec, O_RDONLY); } void ub_unload() { FTRACE(4); if (env) e_free(env); } const char* ub_getenv(const char *csSec, const char *csName) { char *e, *nxt; size_t dlen; const char *str = NULL; FTRACE(3); str = cfg_getAttribute(&cfg, csSec, "size"); if (!str) return NULL; dlen = strtol(str, NULL, 0); if (!dlen) return NULL; else dlen--; for (e = env->env_data; *e; e = nxt + 1) { for (nxt = e; *nxt; nxt++) if (nxt >= env->env_data + dlen) { printf("Error:: environment not terminated\n"); return NULL; } str = ub_envmatch(csName, e); if (str) break; } return str; } int ub_setenv(const char *csSec, const char *csName, const char *csValue) { char *e, *nxt; size_t dlen, len; const char *str, *old = NULL; FTRACE(3); str = cfg_getAttribute(&cfg, csSec, "size"); if (!str) return -1; dlen = strtol(str, NULL, 0); if (!dlen) return -1; else dlen--; for (e = env->env_data; *e; e = nxt + 1) { for (nxt = e; *nxt; nxt++) if (nxt >= env->env_data + dlen) { printf("Error:: environment not terminated\n"); return -1; } old = ub_envmatch(csName, e); if (old) break; } /* Delete any existing definition */ if (old) { if (!*++nxt) *e = 0; else while (42) { *e = *nxt++; if (!*e && !*nxt) break; e++; } *++e = 0; } if (csValue) { /* Append new definition at the end */ for (e = env->env_data; *e || *(e + 1); e++); if (e > env->env_data) e++; /* "name" + "=" + "val" +"\0\0" > u-boot-env size */ len = strlen(csName) + 2; /* add '=' for first arg, ' ' for all others */ len += strlen(csValue) + 1; if (len > env->env_data + dlen - e) { printf("Error:: Environment overflow!\n"); return -1; } /* av pair */ while ((*e = *csName++)) e++; *e = '='; while ((*++e = *csValue++)); /* end is marked with double '\0' */ *++e = 0; } if (ub_flash_io(csSec, O_RDWR)) { printf("Error:: Can't write environment to flash!\n"); return -1; } return 0; } int ub_env(const char *csSec) { char *e, *nxt; size_t dlen; const char *str; FTRACE(3); str = cfg_getAttribute(&cfg, csSec, "size"); if (!str) return -1; dlen = strtol(str, NULL, 0); if (!dlen) return -1; else dlen--; for (e = env->env_data; *e; e = nxt + 1) { for (nxt = e; *nxt; nxt++) if (nxt >= env->env_data + dlen) { printf("Error:: environment not terminated\n"); return -1; } printf("%s\n", e); } return 0; }