/* * Convert a string variable, in the format of blob2string(), to a blob. * Return NULL when conversion failed. */ blob_T * string2blob(char_u *str) { blob_T *blob = blob_alloc(); char_u *s = str; if (*s != '[') goto failed; s = skipwhite(s + 1); while (*s != ']') { if (s[0] != '0' || s[1] != 'x' || !vim_isxdigit(s[2]) || !vim_isxdigit(s[3])) goto failed; ga_append(&blob->bv_ga, (hex2nr(s[2]) << 4) + hex2nr(s[3])); s += 4; if (*s == ',') s = skipwhite(s + 1); else if (*s != ']') goto failed; } s = skipwhite(s + 1); if (*s != NUL) goto failed; // text after final ']' ++blob->bv_refcount; return blob; failed: blob_free(blob); return NULL; }
static void ubus_rawsocket_client_delete(struct ubus_rawsocket_client **self){ shutdown((*self)->fd, SHUT_RDWR); close((*self)->fd); blob_free(&(*self)->data); free(*self); *self = NULL; }
char *buffer_read_string(uint32_t len) { char *s; blob_free(blob_pool.size); s = blob_pointer(blob_alloc(len + 1)); s[fread(s, 1, len, infile)] = '\0'; return ferror(infile) ? NULL : s; }
struct blob *blob_parse(const char *blob, size_t len, const unsigned char key[KDF_HASH_LEN], const struct private_key *private_key) { struct blob_pos blob_pos = { .data = blob, .len = len }; struct chunk chunk; struct account *account, **next_account; struct field *field, **next_field = NULL; struct share *last_share = NULL; struct blob *parsed; _cleanup_free_ char *versionstr = NULL; parsed = new0(struct blob, 1); parsed->local_version = false; next_account = &parsed->account_head; while (read_chunk(&blob_pos, &chunk)) { if (!strcmp(chunk.name, "LPAV")) { versionstr = xstrndup(chunk.data, chunk.len); parsed->version = strtoull(versionstr, NULL, 10); } else if (!strcmp(chunk.name, "ACCT")) { account = account_parse(&chunk, last_share ? last_share->key : key); if (!account) goto error; share_assign(last_share, &account->share); *next_account = account; next_account = &account->next; next_field = &account->field_head; } else if (!strcmp(chunk.name, "ACFL") || !strcmp(chunk.name, "ACOF")) { if (!next_field) goto error; field = field_parse(&chunk, last_share ? last_share->key : key); if (!field) goto error; *next_field = field; next_field = &field->next; } else if (!strcmp(chunk.name, "LOCL")) parsed->local_version = true; else if (!strcmp(chunk.name, "SHAR")) { share_free(last_share); share_assign(share_parse(&chunk, private_key), &last_share); } } if (!versionstr) goto error; if (!parsed->account_head) goto error; share_free(last_share); return parsed; error: share_free(last_share); blob_free(parsed); return NULL; }
void free(void *ptr) { if (!ptr) return; struct bucket_header *header = util_ptr_to_header(ptr); if (header->type == BUCKET_TYPE_BLOB) { blob_free(header); } else { size_t index = bucket_get_index(header, ptr); record_free(header, index); } }
static struct blob *blob_get_latest(struct session *session, const unsigned char key[KDF_HASH_LEN]) { struct blob *local; unsigned long long remote_version; local = local_blob(key, &session->private_key); if (!local) return lastpass_get_blob(session, key); remote_version = lastpass_get_blob_version(session, key); if (remote_version == 0) { blob_free(local); return NULL; } if (local->version < remote_version || (local->local_version && local->version == remote_version)) { blob_free(local); return lastpass_get_blob(session, key); } config_touch("blob"); return local; }
static int compile_shader(const char *fn, GLint type, GLuint *id) { uint8_t *ptr; size_t len; const GLchar *gpt; GLint gsz; GLint compiled; GLint s; ptr = blob_from_file(fn, &len); if ( NULL == ptr ) goto err; s = glCreateShader(type); if ( !s ) goto err_free; gpt = (GLchar *)ptr; gsz = len; glShaderSource(s, 1, &gpt, &gsz); glCompileShader(s); glGetShaderiv(s, GL_COMPILE_STATUS, &compiled); if ( !compiled ) { con_printf("compile_shader: %s: %s\n", fn, get_shader_infolog(s)); goto err_del; } *id = s; blob_free(ptr, len); return 1; err_del: glDeleteShader(s); err_free: blob_free(ptr, len); err: return 0; }
int cmd_rm(int argc, char **argv) { unsigned char key[KDF_HASH_LEN]; struct session *session = NULL; struct blob *blob = NULL; static struct option long_options[] = { {"sync", required_argument, NULL, 'S'}, {"color", required_argument, NULL, 'C'}, {0, 0, 0, 0} }; int option; int option_index; char *name; enum blobsync sync = BLOB_SYNC_AUTO; struct account *found; while ((option = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { switch (option) { case 'S': sync = parse_sync_string(optarg); break; case 'C': terminal_set_color_mode( parse_color_mode_string(optarg)); break; case '?': default: die_usage(cmd_rm_usage); } } if (argc - optind != 1) die_usage(cmd_rm_usage); name = argv[optind]; init_all(sync, key, &session, &blob); found = find_unique_account(blob, name); if (!found) die("Could not find specified account '%s'.", name); if (found->share && found->share->readonly) die("%s is a readonly shared entry from %s. It cannot be deleted.", found->fullname, found->share->name); list_del(&found->list); lastpass_remove_account(sync, key, session, found, blob); blob_save(blob, key); account_free(found); session_free(session); blob_free(blob); return 0; }
ham_status_t extkey_remove(ham_db_t *db, ham_offset_t blobid) { ham_status_t st; if (db_get_extkey_cache(db)) { st=extkey_cache_remove(db_get_extkey_cache(db), blobid); if (st && st!=HAM_KEY_NOT_FOUND) return (st); } return (blob_free(db_get_env(db), db, blobid, 0)); }
static int l_json_parse(lua_State *L){ const char *str = lua_tostring(L, 1); struct blob tmp; blob_init(&tmp, 0, 0); if(!blob_put_json(&tmp, str)){ // put emtpy object if json was invalid! blob_offset_t b = blob_open_table(&tmp); blob_close_table(&tmp, b); } /* if(orange_debug_level >= JUCI_DBG_TRACE){ TRACE("lua blob: "); blob_dump_json(&tmp); } */ orange_lua_blob_to_table(L, blob_field_first_child(blob_head(&tmp)), true); blob_free(&tmp); return 1; }
int cmd_sync(int argc, char **argv) { unsigned char key[KDF_HASH_LEN]; struct session *session = NULL; struct blob *blob = NULL; static struct option long_options[] = { {"background", no_argument, NULL, 'b'}, {"color", required_argument, NULL, 'C'}, {0, 0, 0, 0} }; int option; int option_index; bool background = false; while ((option = getopt_long(argc, argv, "b", long_options, &option_index)) != -1) { switch (option) { case 'b': background = true; break; case 'C': terminal_set_color_mode( parse_color_mode_string(optarg)); break; case '?': default: die_usage(cmd_sync_usage); } } init_all(0, key, &session, NULL); upload_queue_ensure_running(key, session); if (!background) { while (upload_queue_is_running()) usleep(1000000 / 3); } session_free(session); blob_free(blob); return 0; }
ham_status_t blob_duplicate_erase(ham_db_t *db, ham_offset_t table_id, ham_size_t position, ham_u32_t flags, ham_offset_t *new_table_id) { ham_status_t st; ham_record_t rec; ham_size_t i; dupe_table_t *table; ham_offset_t rid; ham_env_t *env = db_get_env(db); /* store the public record pointer, otherwise it's destroyed */ ham_size_t rs=db_get_record_allocsize(db); void *rp=db_get_record_allocdata(db); db_set_record_allocdata(db, 0); db_set_record_allocsize(db, 0); memset(&rec, 0, sizeof(rec)); if (new_table_id) *new_table_id=table_id; st=blob_read(db, table_id, &rec, 0); if (st) return (st); /* restore the public record pointer */ db_set_record_allocsize(db, rs); db_set_record_allocdata(db, rp); table=(dupe_table_t *)rec.data; /* * if BLOB_FREE_ALL_DUPES is set *OR* if the last duplicate is deleted: * free the whole duplicate table */ if (flags&BLOB_FREE_ALL_DUPES || (position==0 && dupe_table_get_count(table)==1)) { for (i=0; i<dupe_table_get_count(table); i++) { dupe_entry_t *e=dupe_table_get_entry(table, i); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { st=blob_free(env, db, dupe_entry_get_rid(e), 0); if (st) { allocator_free(env_get_allocator(env), table); return (st); } } } st=blob_free(env, db, table_id, 0); /* [i_a] isn't this superfluous (& * dangerous), thanks to the * free_all_dupes loop above??? */ allocator_free(env_get_allocator(env), table); if (st) return (st); if (new_table_id) *new_table_id=0; return (0); } else { ham_record_t rec={0}; dupe_entry_t *e=dupe_table_get_entry(table, position); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { st=blob_free(env, db, dupe_entry_get_rid(e), 0); if (st) { allocator_free(env_get_allocator(env), table); return (st); } } memmove(e, e+1, ((dupe_table_get_count(table)-position)-1)*sizeof(dupe_entry_t)); dupe_table_set_count(table, dupe_table_get_count(table)-1); rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_overwrite(env, db, table_id, &rec, 0, &rid); if (st) { allocator_free(env_get_allocator(env), table); return (st); } if (new_table_id) *new_table_id=rid; } /* * return 0 as a rid if the table is empty */ if (dupe_table_get_count(table)==0) if (new_table_id) *new_table_id=0; allocator_free(env_get_allocator(env), table); return (0); }
ham_status_t blob_duplicate_insert(ham_db_t *db, ham_offset_t table_id, ham_record_t *record, ham_size_t position, ham_u32_t flags, dupe_entry_t *entries, ham_size_t num_entries, ham_offset_t *rid, ham_size_t *new_position) { ham_status_t st=0; dupe_table_t *table=0; ham_bool_t alloc_table=0; ham_bool_t resize=0; ham_page_t *page=0; ham_env_t *env=db_get_env(db); /* * create a new duplicate table if none existed, and insert * the first entry */ if (!table_id) { ham_assert(num_entries==2, ("")); /* allocates space for 8 (!) entries */ table=allocator_calloc(env_get_allocator(env), sizeof(dupe_table_t)+7*sizeof(dupe_entry_t)); if (!table) return HAM_OUT_OF_MEMORY; dupe_table_set_capacity(table, 8); dupe_table_set_count(table, 1); memcpy(dupe_table_get_entry(table, 0), &entries[0], sizeof(entries[0])); /* skip the first entry */ entries++; num_entries--; alloc_table=1; } else { /* * otherwise load the existing table */ st=__get_duplicate_table(&table, &page, env, table_id); ham_assert(st ? table == NULL : 1, (0)); ham_assert(st ? page == NULL : 1, (0)); if (!table) return st ? st : HAM_INTERNAL_ERROR; if (!page && !(env_get_rt_flags(env)&HAM_IN_MEMORY_DB)) alloc_table=1; } if (page) if ((st=ham_log_add_page_before(page))) return (st); ham_assert(num_entries==1, ("")); /* * resize the table, if necessary */ if (!(flags & HAM_OVERWRITE) && dupe_table_get_count(table)+1>=dupe_table_get_capacity(table)) { dupe_table_t *old=table; ham_size_t new_cap=dupe_table_get_capacity(table); if (new_cap < 3*8) new_cap += 8; else new_cap += new_cap/3; table=allocator_calloc(env_get_allocator(env), sizeof(dupe_table_t)+ (new_cap-1)*sizeof(dupe_entry_t)); if (!table) return (HAM_OUT_OF_MEMORY); dupe_table_set_capacity(table, new_cap); dupe_table_set_count(table, dupe_table_get_count(old)); memcpy(dupe_table_get_entry(table, 0), dupe_table_get_entry(old, 0), dupe_table_get_count(old)*sizeof(dupe_entry_t)); if (alloc_table) allocator_free(env_get_allocator(env), old); alloc_table=1; resize=1; } /* * insert sorted, unsorted or overwrite the entry at the requested position */ if (flags&HAM_OVERWRITE) { dupe_entry_t *e=dupe_table_get_entry(table, position); if (!(dupe_entry_get_flags(e)&(KEY_BLOB_SIZE_SMALL |KEY_BLOB_SIZE_TINY |KEY_BLOB_SIZE_EMPTY))) { (void)blob_free(env, db, dupe_entry_get_rid(e), 0); } memcpy(dupe_table_get_entry(table, position), &entries[0], sizeof(entries[0])); } else { if (db_get_rt_flags(db)&HAM_SORT_DUPLICATES) { if (page) page_add_ref(page); position=__get_sorted_position(db, table, record, flags); if (page) page_release_ref(page); if (position<0) return ((ham_status_t)position); } else if (flags&HAM_DUPLICATE_INSERT_BEFORE) { /* do nothing, insert at the current position */ } else if (flags&HAM_DUPLICATE_INSERT_AFTER) { position++; if (position > dupe_table_get_count(table)) position=dupe_table_get_count(table); } else if (flags&HAM_DUPLICATE_INSERT_FIRST) { position=0; } else if (flags&HAM_DUPLICATE_INSERT_LAST) { position=dupe_table_get_count(table); } else { position=dupe_table_get_count(table); } if (position != dupe_table_get_count(table)) { memmove(dupe_table_get_entry(table, position+1), dupe_table_get_entry(table, position), sizeof(entries[0])*(dupe_table_get_count(table)-position)); } memcpy(dupe_table_get_entry(table, position), &entries[0], sizeof(entries[0])); dupe_table_set_count(table, dupe_table_get_count(table)+1); } /* * write the table back to disk and return the blobid of the table */ if ((table_id && !page) || resize) { ham_record_t rec={0}; rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_overwrite(env, db, table_id, &rec, 0, rid); } else if (!table_id) { ham_record_t rec={0}; rec.data=(ham_u8_t *)table; rec.size=sizeof(dupe_table_t) +(dupe_table_get_capacity(table)-1)*sizeof(dupe_entry_t); st=blob_allocate(env, db, &rec, 0, rid); } else if (table_id && page) { page_set_dirty(page, env); } else { ham_assert(!"shouldn't be here", (0)); } if (alloc_table) allocator_free(env_get_allocator(env), table); if (new_position) *new_position=position; return (st); }
int main(void){ orange_debug_level+=4; struct orange *app = orange_new("test-plugins", "test-pwfile", "test-acls"); struct blob out; struct blob args; blob_init(&out, 0, 0); blob_init(&args, 0, 0); blob_offset_t o = blob_open_table(&args); blob_put_string(&args, "cmd"); blob_put_string(&args, "echo 'Hello From Defferred!'"); blob_put_string(&args, "msg"); blob_put_string(&args, "Hello You"); blob_put_string(&args, "arr"); blob_offset_t a = blob_open_array(&args); blob_put_int(&args, 1); blob_offset_t t = blob_open_table(&args); blob_put_string(&args, "a"); blob_put_string(&args, "b"); blob_close_table(&args, t); blob_close_array(&args, a); blob_close_table(&args, o); struct orange_user *admin = orange_user_new("admin"); orange_user_add_acl(admin, "test-acl"); orange_add_user(app, &admin); struct orange_sid sid; TEST(orange_login_plaintext(app, "admin", "admin", &sid) == 0); TEST(orange_call(app, sid.hash, "/test", "echo", blob_field_first_child(blob_head(&args)), &out) == 0); TEST(orange_call(app, sid.hash, "/test", "noexist", blob_field_first_child(blob_head(&args)), &out) < 0); TEST(orange_call(app, sid.hash, "/test", "test_c_calls", blob_field_first_child(blob_head(&args)), &out) == 0); // test deferred struct blob def_args; blob_init(&def_args, 0, 0); o = blob_open_table(&def_args); blob_put_string(&def_args, "cmd"); char cmd[64]; char cookie[16]; snprintf(cookie, sizeof(cookie), "%lu", time(NULL)); snprintf(cmd, sizeof(cmd), "printf %s > test-deferred.out", cookie); blob_put_string(&def_args, cmd); blob_close_table(&def_args, o); int r = system("rm test-deferred.out"); TEST(orange_call(app, sid.hash, "/test", "deferred_shell", blob_field_first_child(blob_head(&def_args)), &out) == 0); FILE *f; sleep(2); TEST((f = fopen("test-deferred.out", "r")) == NULL); sleep(3); TEST(f = fopen("test-deferred.out", "r")); // try to read the file char cmdr[32] = {0}; TEST(fread(cmdr, 1, 32, f) > 0); TEST(strcmp(cookie, cmdr) == 0); blob_free(&def_args); TEST(orange_logout(app, sid.hash) == 0); blob_free(&out); blob_free(&args); orange_delete(&app); return 0; }
static void upload_queue_upload_all(const struct session *session, unsigned const char key[KDF_HASH_LEN]) { char *entry, *next_entry, *result; int size; char **argv = NULL; char **argv_ptr; char *name, *lock, *p; bool do_break; bool should_fetch_new_blob_after = false; int curl_ret; long http_code; bool http_failed_all; int backoff; while ((entry = upload_queue_next_entry(key, &name, &lock))) { size = 0; for (p = entry; *p; ++p) { if (*p == '\n') ++size; } if (p > entry && p[-1] != '\n') ++size; if (size < 1) { config_unlink(name); config_unlink(lock); goto end; } argv_ptr = argv = xcalloc(size + 1, sizeof(char **)); for (do_break = false, p = entry, next_entry = entry; ; ++p) { if (!*p) do_break = true; if (*p == '\n' || !*p) { *p = '\0'; *(argv_ptr++) = pinentry_unescape(next_entry); next_entry = p + 1; if (do_break) break; } } argv[size] = NULL; http_failed_all = true; backoff = 1; for (int i = 0; i < 5; ++i) { if (i) { sleep(backoff); backoff *= 8; } result = http_post_lastpass_v_noexit(argv[0], session->sessionid, NULL, &argv[1], &curl_ret, &http_code); http_failed_all &= (curl_ret == HTTP_ERROR_CODE || curl_ret == HTTP_ERROR_CONNECT); if (result && strlen(result)) should_fetch_new_blob_after = true; free(result); if (result) break; } if (!result) { /* server failed response 5 times, remove it */ if (http_failed_all) upload_queue_drop(name); config_unlink(lock); } else { config_unlink(name); config_unlink(lock); } for (argv_ptr = argv; *argv_ptr; ++argv_ptr) free(*argv_ptr); free(argv); end: free(name); free(lock); free(entry); } if (should_fetch_new_blob_after) blob_free(lastpass_get_blob(session, key)); }
void ubus_method_destroy(struct ubus_method *self){ if(self->name) free(self->name); blob_free(&self->signature); self->handler = 0; }
static blob_list_ty * ifeq(blob_list_ty *blp, string_list_ty *ref) { blob_ty *arg; blob_ty *bp; blob_list_ty *result; string_ty *s; string_ty *s2; char *cp; size_t j; /* * allocate the result list */ trace(("ifeq()\n{\n")); result = blob_list_alloc(); /* * make sure we were given enough arguments */ if (blp->length < 2) { arg = blp->list[0]; blob_list_append ( result, blob_alloc(str_from_c("0"), arg->file_name, arg->line_number) ); trace(("}\n")); return result; } /* * turn the list of arguments into a single string */ arg = blp->list[1]; s = str_copy(blp->list[1]->text); for (j = 2; j < blp->length; ++j) { s2 = str_format("%s %s", s->str_text, blp->list[j]->text->str_text); str_free(s); s = s2; } bp = blob_alloc(s, arg->file_name, arg->line_number); /* * rename the variables * and reform to be a single string, again. */ variable_rename(bp, result, ref, VAREN_NO_QUOQUO); blob_free(bp); s = result->length ? str_copy(result->list[0]->text) : str_from_c("0"); for (j = 1; j < result->length; ++j) { s2 = str_format("%s %s", s->str_text, result->list[j]->text->str_text); str_free(s); s = s2; } blob_list_free(result); /* * construct the result */ result = blob_list_alloc(); switch (s->str_text[0]) { case '(': /* * ifeq (xxx,yyy) */ if (s->str_length < 3) goto useless; cp = strchr(s->str_text, ','); if (cp == 0 || s->str_text[s->str_length - 1] != ')') goto useless; blob_list_append ( result, blob_alloc(str_from_c("[in"), arg->file_name, arg->line_number) ); s2 = str_n_from_c(s->str_text + 1, cp - s->str_text - 1); if (s2->str_length == 0) s2 = str_from_c("\"\""); bp = blob_alloc(s2, arg->file_name, arg->line_number); blob_list_append(result, bp); s2 = str_n_from_c(cp + 1, s->str_text + s->str_length - cp - 2); if (s2->str_length == 0) s2 = str_from_c("\"\""); bp = blob_alloc(s2, arg->file_name, arg->line_number); blob_list_append(result, bp); blob_list_append ( result, blob_alloc(str_from_c("]"), arg->file_name, arg->line_number) ); break; case '\'': case '"': /* * ifeq "xxx" "yyy" */ if (s->str_length < 5) goto useless; cp = strchr(s->str_text + 1, s->str_text[0]); if ( !cp || cp[1] != ' ' || cp[2] != s->str_text[0] || s->str_text[s->str_length - 1] != s->str_text[0] ) goto useless; blob_list_append ( result, blob_alloc(str_from_c("[in"), arg->file_name, arg->line_number) ); s2 = str_n_from_c(s->str_text + 1, cp - s->str_text - 1); if (s2->str_length == 0) s2 = str_from_c("\"\""); bp = blob_alloc(s2, arg->file_name, arg->line_number); blob_list_append(result, bp); s2 = str_n_from_c(cp + 3, s->str_text + s->str_length - cp - 4); if (s2->str_length == 0) s2 = str_from_c("\"\""); bp = blob_alloc(s2, arg->file_name, arg->line_number); blob_list_append(result, bp); blob_list_append ( result, blob_alloc(str_from_c("]"), arg->file_name, arg->line_number) ); break; default: /* * We were given some useless thing, just rename the * variables and copy it through. */ useless: bp = blob_alloc(str_copy(s), arg->file_name, arg->line_number); blob_list_append(result, bp); break; } str_free(s); trace(("}\n")); return result; }
static void test_blob_new(void) { int rc; char a[BUF_SIZE]; blob_t *bp; uint32_t ms; blob_t *dupbp; int32_t c; memset(a, 'a', sizeof(a)); bp = NULL; rc = blob_new(a, sizeof(a)-1, &bp); assert(rc == 0 && bp != NULL); assert(blob_size(bp) == sizeof(a) - 1); ms = blob_memory_size(bp); assert(blob_size(bp) == ms); rc = blob_init(bp, a, sizeof(a)); assert(rc != 0); assert(blob_size(bp) == sizeof(a) - 1); assert(blob_size(bp) == ms); assert(ms == blob_memory_size(bp)); rc = blob_init(bp, a, 1); assert(rc == 0); assert(blob_size(bp) == 1); assert(ms == blob_memory_size(bp)); dupbp = NULL; rc = blob_dup(bp, &dupbp); assert(rc == 0 && dupbp != NULL); assert(blob_size(dupbp) == 1); assert(blob_memory_size(dupbp) == 1); c = blob_compare(bp, dupbp); assert(c == 0); c = blob_compare(dupbp, bp); assert(c == 0); rc = blob_init(bp, a, sizeof(a)); assert(rc != 0); assert(blob_size(bp) == 1); assert(ms == blob_memory_size(bp)); rc = blob_init(bp, a, sizeof(a)-1); assert(rc == 0); assert(blob_size(bp) == sizeof(a) - 1); assert(blob_size(bp) == ms); assert(ms == blob_memory_size(bp)); c = blob_compare(bp, dupbp); assert(c > 0); assert(c == blob_size(bp) - blob_size(dupbp)); c = blob_compare(dupbp, bp); assert(c < 0); assert(c == blob_size(dupbp) - blob_size(bp)); blob_free(bp); bp = NULL; blob_free(dupbp); dupbp = NULL; }
int cmd_export(int argc, char **argv) { static struct option long_options[] = { {"sync", required_argument, NULL, 'S'}, {"color", required_argument, NULL, 'C'}, {0, 0, 0, 0} }; int option; int option_index; enum blobsync sync = BLOB_SYNC_AUTO; while ((option = getopt_long(argc, argv, "c", long_options, &option_index)) != -1) { switch (option) { case 'S': sync = parse_sync_string(optarg); break; case 'C': terminal_set_color_mode( parse_color_mode_string(optarg)); break; case '?': default: die_usage(cmd_export_usage); } } unsigned char key[KDF_HASH_LEN]; struct session *session = NULL; struct blob *blob = NULL; init_all(sync, key, &session, &blob); /* reprompt once if any one account is password protected */ for (struct account *account = blob->account_head; account; account = account->next) { if (account->pwprotect) { unsigned char pwprotect_key[KDF_HASH_LEN]; if (!agent_load_key(pwprotect_key)) die("Could not authenticate for protected entry."); if (memcmp(pwprotect_key, key, KDF_HASH_LEN)) die("Current key is not on-disk key."); break; } } printf("url,username,password,hostname,name,grouping\r\n"); for (struct account *account = blob->account_head; account; account = account->next) { /* skip shared notes */ if (!strcmp(account->url, "http://sn")) continue; lastpass_log_access(sync, session, key, account); print_csv_cell(account->url, false); print_csv_cell(account->username, false); print_csv_cell(account->password, false); print_csv_cell(account->fullname, false); print_csv_cell(account->name, false); print_csv_cell(account->group, true); } session_free(session); blob_free(blob); return 0; }
/* * Unreference a blob: decrement the reference count and free it when it * becomes zero. */ void blob_unref(blob_T *b) { if (b != NULL && --b->bv_refcount <= 0) blob_free(b); }