/* * Read $LANG and parse ll_CC.UTF8 format where * - ‘ll’ is an ISO 639 two-letter language code (lowercase). * - ‘CC’ is an ISO 3166 two-letter country code (uppercase). */ static void find_translation_file_within_dir(struct sbuf *s) { char *p; struct stat st; p = getenv("LANG"); if (!p) { warn("LANG not set - cannot not find translation file"); sbuf_cpy(s, ""); return; } if (s->buf[s->len] != '/') sbuf_addch(s, '/'); sbuf_addstr(s, p); /* try ll_CC */ if (strchr(getenv("LANG"), '.')) { p = strrchr(s->buf, '.'); BUG_ON(!p); *p = '\0'; } if (!stat(s->buf, &st)) return; /* try ll */ if (strchr(getenv("LANG"), '_')) { p = strrchr(s->buf, '_'); BUG_ON(!p); *p = '\0'; } if (stat(s->buf, &st) < 0) sbuf_cpy(s, ""); }
void mkdir_p(const char *path) { struct sbuf s; char *p; sbuf_init(&s); if (strlen(path) > PATH_MAX) { warn("mkdir_p: path too long"); return; } sbuf_cpy(&s, path); if (!s.len) return; sbuf_expand_tilde(&s); if (s.buf[s.len - 1] != '/') sbuf_addch(&s, '/'); for (p = s.buf + 1; *p; p++) { if (*p != '/') continue; *p = '\0'; if (mkdir(s.buf, S_IRWXU) != 0 && errno != EEXIST) warn("mkdir_p: could not create '%s'", s.buf); *p = '/'; } }
void i18n_translate_first_field(struct sbuf *s) { char *tmp, *remainder = NULL, *translation = NULL; BUG_ON(!s || !s->buf); if (s->buf[0] == '\0') return; /* Make a copy as we leave 's' untouched if no translation exists */ tmp = xstrdup(s->buf); remainder = strchr(tmp, ','); if (remainder) { *remainder = '\0'; ++remainder; } /* tmp now contains the first field, which we want to translate */ translation = i18n_translate(tmp); if (translation) { sbuf_cpy(s, translation); if (remainder) { sbuf_addch(s, ','); sbuf_addstr(s, remainder); } } xfree(tmp); }
char *i18n_set_translation_file(const char *filename) { struct stat st; struct sbuf s; sbuf_init(&s); sbuf_cpy(&s, filename); sbuf_expand_tilde(&s); if (stat(s.buf, &st) < 0) { warn("i18n: file '%s' does not exist", s.buf); translation_file = NULL; xfree(s.buf); return NULL; } if (S_ISDIR(st.st_mode)) { find_translation_file_within_dir(&s); if (!s.len) { warn("i18n: could not find translation file in dir '%s'", filename); translation_file = NULL; xfree(s.buf); return NULL; } } translation_file = s.buf; info("i18n: translation file '%s' loaded", translation_file); i18n_open(); return translation_file; }
int sbuf_set(struct sbuf **buf, const char *str) { if (*buf == NULL) *buf = sbuf_new_auto(); if (str == NULL) return (-1); sbuf_cpy(*buf, str); sbuf_finish(*buf); return (0); }
/* * Output a value of a variable, except if there is a fill value for * the variable and the value is the fill value, print the fill-value string * instead. (Floating-point fill values need only be within machine epsilon of * defined fill value.) */ static void print_any_val( safebuf_t *sb, /* string where output goes */ const ncvar_t *varp, /* variable */ const void *valp /* pointer to the value */ ) { if (varp->has_fillval && (*(varp->tinfo->val_equals))((const nctype_t *)varp->tinfo, (const void*)varp->fillvalp, valp) ) { sbuf_cpy(sb, FILL_STRING); } else { (*varp->val_tostring)(varp, sb, valp); } }
void cat(const char *filename) { FILE *fp; char line[4096]; struct sbuf f; sbuf_init(&f); sbuf_cpy(&f, filename); sbuf_expand_tilde(&f); fp = fopen(f.buf, "r"); if (!fp) goto cleanup; while (fgets(line, sizeof(line), fp)) printf("%s", line); printf("\n"); fclose(fp); cleanup: xfree(f.buf); }
int main(int argc, char **argv) { int i; struct sbuf s; if (argc < 2) usage(); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') icon_name = argv[i]; if (!strncmp(argv[i], "--icon-size=", 12)) xatoi(&icon_size, argv[i] + 12, XATOI_NONNEG, "config.icon_size"); if (!strncmp(argv[i], "--theme=", 8)) theme = argv[i] + 8; if (!strncmp(argv[i], "--help", 6)) usage(); } if (!icon_name) { fprintf(stderr, "fatal: no icon-name specified\n"); exit(1); } sbuf_init(&s); icon_find_init(); if (theme) icon_find_add_theme(theme); else icon_find_add_theme("default"); icon_find_add_theme("hicolor"); sbuf_cpy(&s, icon_name); icon_find(&s, icon_size); if (s.len) printf("%s\n", s.buf); else fprintf(stderr, "warning: could not find icon '%s'\n", icon_name); return 0; }
static void i18n_open(void) { struct stat sb; struct sbuf s; static int has_run; if (!has_run) { hashmap_init(&map, (hashmap_cmp_fn) cmp, 0); has_run = 1; } BUG_ON(!translation_file); if (translation_file[0] == '\0') return; sbuf_init(&s); sbuf_cpy(&s, translation_file); sbuf_expand_tilde(&s); if (stat(s.buf, &sb) < 0) die("%s: stat()", __func__); parse_file(s.buf); xfree(s.buf); }
static void config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype) { struct sbuf *buf = sbuf_new_auto(); const ucl_object_t *cur, *seq; ucl_object_iter_t it = NULL, itseq = NULL; struct config_entry *temp_config; struct config_value *cv; const char *key; int i; size_t j; /* Temporary config for configs that may be disabled. */ temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry)); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; sbuf_clear(buf); if (conftype == CONFFILE_PKG) { for (j = 0; j < strlen(key); ++j) sbuf_putc(buf, key[j]); sbuf_finish(buf); } else if (conftype == CONFFILE_REPO) { if (strcasecmp(key, "url") == 0) sbuf_cpy(buf, "PACKAGESITE"); else if (strcasecmp(key, "mirror_type") == 0) sbuf_cpy(buf, "MIRROR_TYPE"); else if (strcasecmp(key, "signature_type") == 0) sbuf_cpy(buf, "SIGNATURE_TYPE"); else if (strcasecmp(key, "fingerprints") == 0) sbuf_cpy(buf, "FINGERPRINTS"); else if (strcasecmp(key, "enabled") == 0) { if ((cur->type != UCL_BOOLEAN) || !ucl_object_toboolean(cur)) goto cleanup; } else continue; sbuf_finish(buf); } for (i = 0; i < CONFIG_SIZE; i++) { if (strcmp(sbuf_data(buf), c[i].key) == 0) break; } /* Silently skip unknown keys to be future compatible. */ if (i == CONFIG_SIZE) continue; /* env has priority over config file */ if (c[i].envset) continue; /* Parse sequence value ["item1", "item2"] */ switch (c[i].type) { case PKG_CONFIG_LIST: if (cur->type != UCL_ARRAY) { warnx("Skipping invalid array " "value for %s.\n", c[i].key); continue; } temp_config[i].list = malloc(sizeof(*temp_config[i].list)); STAILQ_INIT(temp_config[i].list); while ((seq = ucl_iterate_object(cur, &itseq, true))) { if (seq->type != UCL_STRING) continue; cv = malloc(sizeof(struct config_value)); cv->value = strdup(ucl_object_tostring(seq)); STAILQ_INSERT_TAIL(temp_config[i].list, cv, next); } break; case PKG_CONFIG_BOOL: temp_config[i].value = strdup(ucl_object_toboolean(cur) ? "yes" : "no"); break; default: /* Normal string value. */ temp_config[i].value = strdup(ucl_object_tostring(cur)); break; } } /* Repo is enabled, copy over all settings from temp_config. */ for (i = 0; i < CONFIG_SIZE; i++) { if (c[i].envset) continue; /* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */ if (conftype != CONFFILE_PKG && c[i].main_only == true) continue; switch (c[i].type) { case PKG_CONFIG_LIST: c[i].list = temp_config[i].list; break; default: c[i].value = temp_config[i].value; break; } } cleanup: free(temp_config); sbuf_delete(buf); }
int main(int argc, char *argv[]) { #define STDIN_BUF_SZ 1024 char stdin_data[STDIN_BUF_SZ]; char *p; const char *options, *attrname; size_t len; ssize_t ret; int ch, error, i, arg_counter, attrnamespace, minargc; char *visbuf = NULL; int visbuflen = 0; char *buf = NULL; int buflen = 0; struct sbuf *attrvalue = NULL; int flag_force = 0; int flag_nofollow = 0; int flag_null = 0; int count_quiet = 0; int flag_from_stdin = 0; int flag_string = 0; int flag_hex = 0; p = basename(argv[0]); if (p == NULL) p = argv[0]; if (!strcmp(p, "getextattr")) { what = EAGET; options = "fhqsx"; minargc = 3; } else if (!strcmp(p, "setextattr")) { what = EASET; options = "fhinq"; minargc = 3; } else if (!strcmp(p, "rmextattr")) { what = EARM; options = "fhq"; minargc = 3; } else if (!strcmp(p, "lsextattr")) { what = EALS; options = "fhq"; minargc = 2; } else { usage(); } while ((ch = getopt(argc, argv, options)) != -1) { switch (ch) { case 'f': flag_force = 1; break; case 'h': flag_nofollow = 1; break; case 'i': flag_from_stdin = 1; break; case 'n': flag_null = 1; break; case 'q': count_quiet += 1; break; case 's': flag_string = 1; break; case 'x': flag_hex = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (what == EASET && flag_from_stdin == 0) minargc++; if (argc < minargc) usage(); error = extattr_string_to_namespace(argv[0], &attrnamespace); if (error) err(-1, "%s", argv[0]); argc--; argv++; if (what != EALS) { attrname = argv[0]; argc--; argv++; } else attrname = NULL; if (what == EASET) { attrvalue = sbuf_new_auto(); if (flag_from_stdin) { while ((error = read(0, stdin_data, STDIN_BUF_SZ)) > 0) sbuf_bcat(attrvalue, stdin_data, error); } else { sbuf_cpy(attrvalue, argv[0]); argc--; argv++; } sbuf_finish(attrvalue); } for (arg_counter = 0; arg_counter < argc; arg_counter++) { switch (what) { case EARM: if (flag_nofollow) error = extattr_delete_link(argv[arg_counter], attrnamespace, attrname); else error = extattr_delete_file(argv[arg_counter], attrnamespace, attrname); if (error >= 0) continue; break; case EASET: len = sbuf_len(attrvalue) + flag_null; if (flag_nofollow) ret = extattr_set_link(argv[arg_counter], attrnamespace, attrname, sbuf_data(attrvalue), len); else ret = extattr_set_file(argv[arg_counter], attrnamespace, attrname, sbuf_data(attrvalue), len); if (ret >= 0) { if ((size_t)ret != len && !count_quiet) { warnx("Set %zd bytes of %zu for %s", ret, len, attrname); } continue; } break; case EALS: if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, NULL, 0); else ret = extattr_list_file(argv[arg_counter], attrnamespace, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, buf, buflen); else ret = extattr_list_file(argv[arg_counter], attrnamespace, buf, buflen); if (ret < 0) break; if (!count_quiet) printf("%s\t", argv[arg_counter]); for (i = 0; i < ret; i += ch + 1) { /* The attribute name length is unsigned. */ ch = (unsigned char)buf[i]; printf("%s%*.*s", i ? "\t" : "", ch, ch, buf + i + 1); } if (!count_quiet || ret > 0) printf("\n"); continue; case EAGET: if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, NULL, 0); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, buf, buflen); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, buf, buflen); if (ret < 0) break; if (!count_quiet) printf("%s\t", argv[arg_counter]); if (flag_string) { mkbuf(&visbuf, &visbuflen, ret * 4 + 1); strvisx(visbuf, buf, ret, VIS_SAFE | VIS_WHITE); printf("\"%s\"", visbuf); } else if (flag_hex) { for (i = 0; i < ret; i++) printf("%s%02x", i ? " " : "", (unsigned char)buf[i]); } else { fwrite(buf, ret, 1, stdout); } if (count_quiet < 2) printf("\n"); continue; default: break; } if (!count_quiet) warn("%s: failed", argv[arg_counter]); if (flag_force) continue; return(1); } return (0); }