static int do_env_delete(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int env_flag = H_INTERACTIVE; int ret = 0; debug("Initial value for argc=%d\n", argc); while (argc > 1 && **(argv + 1) == '-') { char *arg = *++argv; --argc; while (*++arg) { switch (*arg) { case 'f': /* force */ env_flag |= H_FORCE; break; default: return CMD_RET_USAGE; } } } debug("Final value for argc=%d\n", argc); env_id++; while (--argc > 0) { char *name = *++argv; if (!hdelete_r(name, &env_htab, env_flag)) ret = 1; } return ret; }
int _do_env_set (int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; int i, len; int console = -1; char *name, *value, *s; ENTRY e, *ep; name = argv[1]; if (strchr(name, '=')) { printf("## Error: illegal character '=' in variable name \"%s\"\n", name); return 1; } env_id++; /* * search if variable with this name already exists */ e.key = name; e.data = NULL; hsearch_r(e, FIND, &ep, &env_htab); /* Check for console redirection */ if (strcmp(name, "stdin") == 0) console = stdin; else if (strcmp(name, "stdout") == 0) console = stdout; else if (strcmp(name, "stderr") == 0) console = stderr; if (console != -1) { if (argc < 3) { /* Cannot delete it! */ printf("Can't delete \"%s\"\n", name); return 1; } #ifdef CONFIG_CONSOLE_MUX i = iomux_doenv(console, argv[2]); if (i) return i; #else /* Try assigning specified device */ if (console_assign(console, argv[2]) < 0) return 1; #ifdef CONFIG_SERIAL_MULTI if (serial_assign(argv[2]) < 0) return 1; #endif #endif /* CONFIG_CONSOLE_MUX */ } /* * Some variables like "ethaddr" and "serial#" can be set only * once and cannot be deleted; also, "ver" is readonly. */ if (ep) { /* variable exists */ #ifndef CONFIG_ENV_OVERWRITE if ((strcmp(name, "serial#") == 0) || ((strcmp(name, "ethaddr") == 0) #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) && (strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0) #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ ) ) { printf("Can't overwrite \"%s\"\n", name); return 1; } #endif /* * Switch to new baudrate if new baudrate is supported */ if (strcmp(name, "baudrate") == 0) { int baudrate = simple_strtoul(argv[2], NULL, 10); int i; for (i = 0; i < N_BAUDRATES; ++i) { if (baudrate == baudrate_table[i]) break; } if (i == N_BAUDRATES) { printf("## Baudrate %d bps not supported\n", baudrate); return 1; } printf ("## Switch baudrate to %d bps and press ENTER ...\n", baudrate); udelay(50000); gd->baudrate = baudrate; #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) gd->bd->bi_baudrate = baudrate; #endif serial_setbrg(); udelay(50000); for (;;) { if (getc() == '\r') break; } } } /* Delete only ? */ if ((argc < 3) || argv[2] == NULL) { int rc = hdelete_r(name, &env_htab); return !rc; } /* * Insert / replace new value */ for (i = 2, len = 0; i < argc; ++i) len += strlen(argv[i]) + 1; value = malloc(len); if (value == NULL) { printf("## Can't malloc %d bytes\n", len); return 1; } for (i = 2, s = value; i < argc; ++i) { char *v = argv[i]; while ((*s++ = *v++) != '\0') ; *(s-1) = ' '; } if (s != value) *--s = '\0'; e.key = name; e.data = value; hsearch_r(e, ENTER, &ep, &env_htab); free(value); if (!ep) { printf("## Error inserting \"%s\" variable, errno=%d\n", name, errno); return 1; } /* * Some variables should be updated when the corresponding * entry in the environment is changed */ if (strcmp(name, "ipaddr") == 0) { char *s = argv[2]; /* always use only one arg */ char *e; unsigned long addr; bd->bi_ip_addr = 0; for (addr = 0, i = 0; i < 4; ++i) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; addr <<= 8; addr |= (val & 0xFF); if (s) s = (*e) ? e+1 : e; } bd->bi_ip_addr = htonl(addr); return 0; } else if (strcmp(argv[1], "loadaddr") == 0) { load_addr = simple_strtoul(argv[2], NULL, 16); return 0; } #if defined(CONFIG_CMD_NET) else if (strcmp(argv[1], "bootfile") == 0) { copy_filename(BootFile, argv[2], sizeof(BootFile)); return 0; } #endif return 0; }
int himport_r(struct hsearch_data *htab, const char *env, size_t size, const char sep, int flag, int crlf_is_lf, int nvars, char * const vars[]) { char *data, *sp, *dp, *name, *value; char *localvars[nvars]; int i; /* Test for correct arguments. */ if (htab == NULL) { __set_errno(EINVAL); return 0; } /* we allocate new space to make sure we can write to the array */ if ((data = malloc(size + 1)) == NULL) { debug("himport_r: can't malloc %lu bytes\n", (ulong)size + 1); __set_errno(ENOMEM); return 0; } memcpy(data, env, size); data[size] = '\0'; dp = data; /* make a local copy of the list of variables */ if (nvars) memcpy(localvars, vars, sizeof(vars[0]) * nvars); if ((flag & H_NOCLEAR) == 0) { /* Destroy old hash table if one exists */ debug("Destroy Hash Table: %p table = %p\n", htab, htab->table); if (htab->table) hdestroy_r(htab); } /* * Create new hash table (if needed). The computation of the hash * table size is based on heuristics: in a sample of some 70+ * existing systems we found an average size of 39+ bytes per entry * in the environment (for the whole key=value pair). Assuming a * size of 8 per entry (= safety factor of ~5) should provide enough * safety margin for any existing environment definitions and still * allow for more than enough dynamic additions. Note that the * "size" argument is supposed to give the maximum environment size * (CONFIG_ENV_SIZE). This heuristics will result in * unreasonably large numbers (and thus memory footprint) for * big flash environments (>8,000 entries for 64 KB * environment size), so we clip it to a reasonable value. * On the other hand we need to add some more entries for free * space when importing very small buffers. Both boundaries can * be overwritten in the board config file if needed. */ if (!htab->table) { int nent = CONFIG_ENV_MIN_ENTRIES + size / 8; if (nent > CONFIG_ENV_MAX_ENTRIES) nent = CONFIG_ENV_MAX_ENTRIES; debug("Create Hash Table: N=%d\n", nent); if (hcreate_r(nent, htab) == 0) { free(data); return 0; } } if (!size) { free(data); return 1; /* everything OK */ } if(crlf_is_lf) { /* Remove Carriage Returns in front of Line Feeds */ unsigned ignored_crs = 0; for(;dp < data + size && *dp; ++dp) { if(*dp == '\r' && dp < data + size - 1 && *(dp+1) == '\n') ++ignored_crs; else *(dp-ignored_crs) = *dp; } size -= ignored_crs; dp = data; } /* Parse environment; allow for '\0' and 'sep' as separators */ do { ENTRY e, *rv; /* skip leading white space */ while (isblank(*dp)) ++dp; /* skip comment lines */ if (*dp == '#') { while (*dp && (*dp != sep)) ++dp; ++dp; continue; } /* parse name */ for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) ; /* deal with "name" and "name=" entries (delete var) */ if (*dp == '\0' || *(dp + 1) == '\0' || *dp == sep || *(dp + 1) == sep) { if (*dp == '=') *dp++ = '\0'; *dp++ = '\0'; /* terminate name */ debug("DELETE CANDIDATE: \"%s\"\n", name); if (!drop_var_from_set(name, nvars, localvars)) continue; if (hdelete_r(name, htab, flag) == 0) debug("DELETE ERROR ##############################\n"); continue; } *dp++ = '\0'; /* terminate name */ /* parse value; deal with escapes */ for (value = sp = dp; *dp && (*dp != sep); ++dp) { if ((*dp == '\\') && *(dp + 1)) ++dp; *sp++ = *dp; } *sp++ = '\0'; /* terminate value */ ++dp; if (*name == 0) { debug("INSERT: unable to use an empty key\n"); __set_errno(EINVAL); free(data); return 0; } /* Skip variables which are not supposed to be processed */ if (!drop_var_from_set(name, nvars, localvars)) continue; /* enter into hash table */ e.key = name; e.data = value; hsearch_r(e, ENTER, &rv, htab, flag); if (rv == NULL) printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value); debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n", htab, htab->filled, htab->size, rv, name, value); } while ((dp < data + size) && *dp); /* size check needed for text */ /* without '\0' termination */ debug("INSERT: free(data = %p)\n", data); free(data); /* process variables which were not considered */ for (i = 0; i < nvars; i++) { if (localvars[i] == NULL) continue; /* * All variables which were not deleted from the variable list * were not present in the imported env * This could mean two things: * a) if the variable was present in current env, we delete it * b) if the variable was not present in current env, we notify * it might be a typo */ if (hdelete_r(localvars[i], htab, flag) == 0) printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); else printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); } debug("INSERT: done\n"); return 1; /* everything OK */ }
/* * Set a new environment variable, * or replace or delete an existing one. */ static int _do_env_set(int flag, int argc, char * const argv[]) { int i, len; char *name, *value, *s; ENTRY e, *ep; int env_flag = H_INTERACTIVE; debug("Initial value for argc=%d\n", argc); while (argc > 1 && **(argv + 1) == '-') { char *arg = *++argv; --argc; while (*++arg) { switch (*arg) { case 'f': /* force */ env_flag |= H_FORCE; break; default: return CMD_RET_USAGE; } } } debug("Final value for argc=%d\n", argc); name = argv[1]; value = argv[2]; if (strchr(name, '=')) { printf("## Error: illegal character '='" "in variable name \"%s\"\n", name); return 1; } env_id++; /* Delete only ? */ if (argc < 3 || argv[2] == NULL) { int rc = hdelete_r(name, &env_htab, env_flag); return !rc; } /* * Insert / replace new value */ for (i = 2, len = 0; i < argc; ++i) len += strlen(argv[i]) + 1; value = malloc(len); if (value == NULL) { printf("## Can't malloc %d bytes\n", len); return 1; } for (i = 2, s = value; i < argc; ++i) { char *v = argv[i]; while ((*s++ = *v++) != '\0') ; *(s - 1) = ' '; } if (s != value) *--s = '\0'; e.key = name; e.data = value; hsearch_r(e, ENTER, &ep, &env_htab, env_flag); free(value); if (!ep) { printf("## Error inserting \"%s\" variable, errno=%d\n", name, errno); return 1; } return 0; }
/* * Set a new environment variable, * or replace or delete an existing one. */ int _do_env_set(int flag, int argc, char * const argv[]) { int i, len; char *name, *value, *s; ENTRY e, *ep; name = argv[1]; value = argv[2]; if (strchr(name, '=')) { printf("## Error: illegal character '='" "in variable name \"%s\"\n", name); return 1; } env_id++; /* * search if variable with this name already exists */ e.key = name; e.data = NULL; hsearch_r(e, FIND, &ep, &env_htab); /* * Perform requested checks. Notice how since we are overwriting * a single variable, we need to set H_NOCLEAR */ if (env_check_apply(name, ep ? ep->data : NULL, value, H_NOCLEAR)) { debug("check function did not approve, refusing\n"); return 1; } /* Delete only ? */ if (argc < 3 || argv[2] == NULL) { int rc = hdelete_r(name, &env_htab, 0); return !rc; } /* * Insert / replace new value */ for (i = 2, len = 0; i < argc; ++i) len += strlen(argv[i]) + 1; value = malloc(len); if (value == NULL) { printf("## Can't malloc %d bytes\n", len); return 1; } for (i = 2, s = value; i < argc; ++i) { char *v = argv[i]; while ((*s++ = *v++) != '\0') ; *(s - 1) = ' '; } if (s != value) *--s = '\0'; e.key = name; e.data = value; hsearch_r(e, ENTER, &ep, &env_htab); free(value); if (!ep) { printf("## Error inserting \"%s\" variable, errno=%d\n", name, errno); return 1; } return 0; }
int himport_r(struct hsearch_data *htab, const char *env, size_t size, const char sep, int flag) { char *data, *sp, *dp, *name, *value; /* Test for correct arguments. */ if (htab == NULL) { __set_errno(EINVAL); return 0; } /* we allocate new space to make sure we can write to the array */ if ((data = malloc(size)) == NULL) { debug("himport_r: can't malloc %d bytes\n", size); __set_errno(ENOMEM); return 0; } memcpy(data, env, size); dp = data; if ((flag & H_NOCLEAR) == 0) { /* Destroy old hash table if one exists */ debug("Destroy Hash Table: %p table = %p\n", htab, htab->table); if (htab->table) hdestroy_r(htab); } /* * Create new hash table (if needed). The computation of the hash * table size is based on heuristics: in a sample of some 70+ * existing systems we found an average size of 39+ bytes per entry * in the environment (for the whole key=value pair). Assuming a * size of 8 per entry (= safety factor of ~5) should provide enough * safety margin for any existing environment definitions and still * allow for more than enough dynamic additions. Note that the * "size" argument is supposed to give the maximum enviroment size * (CONFIG_ENV_SIZE). This heuristics will result in * unreasonably large numbers (and thus memory footprint) for * big flash environments (>8,000 entries for 64 KB * envrionment size), so we clip it to a reasonable value. * On the other hand we need to add some more entries for free * space when importing very small buffers. Both boundaries can * be overwritten in the board config file if needed. */ if (!htab->table) { int nent = CONFIG_ENV_MIN_ENTRIES + size / 8; if (nent > CONFIG_ENV_MAX_ENTRIES) nent = CONFIG_ENV_MAX_ENTRIES; debug("Create Hash Table: N=%d\n", nent); if (hcreate_r(nent, htab) == 0) { free(data); return 0; } } /* Parse environment; allow for '\0' and 'sep' as separators */ do { ENTRY e, *rv; /* skip leading white space */ while ((*dp == ' ') || (*dp == '\t')) ++dp; /* skip comment lines */ if (*dp == '#') { while (*dp && (*dp != sep)) ++dp; ++dp; continue; } /* parse name */ for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) ; /* deal with "name" and "name=" entries (delete var) */ if (*dp == '\0' || *(dp + 1) == '\0' || *dp == sep || *(dp + 1) == sep) { if (*dp == '=') *dp++ = '\0'; *dp++ = '\0'; /* terminate name */ debug("DELETE CANDIDATE: \"%s\"\n", name); if (hdelete_r(name, htab) == 0) debug("DELETE ERROR ##############################\n"); continue; } *dp++ = '\0'; /* terminate name */ /* parse value; deal with escapes */ for (value = sp = dp; *dp && (*dp != sep); ++dp) { if ((*dp == '\\') && *(dp + 1)) ++dp; *sp++ = *dp; } *sp++ = '\0'; /* terminate value */ ++dp; /* enter into hash table */ e.key = name; e.data = value; hsearch_r(e, ENTER, &rv, htab); if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value); return 0; } debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n", htab, htab->filled, htab->size, rv, name, value); } while ((dp < data + size) && *dp); /* size check needed for text */ /* without '\0' termination */ debug("INSERT: free(data = %p)\n", data); free(data); debug("INSERT: done\n"); return 1; /* everything OK */ }