/* verify that required db files exist */ static int check_db_files(alpm_pkg_t *pkg) { const char *pkgname = alpm_pkg_get_name(pkg); char *dbpath; int ret = 0; if((dbpath = get_db_path(pkg, "desc")) == NULL) { pu_ui_warn("%s: '%s' read error (%s)", pkgname, dbpath, strerror(errno)); } else if(check_file(pkgname, dbpath, 0) != 0) { ret = 1; } if((dbpath = get_db_path(pkg, "files")) == NULL) { pu_ui_warn("%s: '%s' read error (%s)", pkgname, dbpath, strerror(errno)); } else if(check_file(pkgname, dbpath, 0) != 0) { ret = 1; } if(!require_mtree) { return ret; } if((dbpath = get_db_path(pkg, "mtree")) == NULL) { pu_ui_warn("%s: '%s' read error (%s)", pkgname, dbpath, strerror(errno)); } else if(check_file(pkgname, dbpath, 0) != 0) { ret = 1; } return ret; }
int main(int argc, const char **argv) { usage(argc); get_db_path(argc, argv); get_name(argc, argv); open_db(); create_table(); generate_keypair(); insert_keypair(); close_db(); return 0; }
/* -------------------------------- * init_postgres * Initialize POSTGRES. * * The database can be specified by name, using the in_dbname parameter, or by * OID, using the dboid parameter. In the latter case, the actual database * name can be returned to the caller in out_dbname. If out_dbname isn't * NULL, it must point to a buffer of size NAMEDATALEN. * * In bootstrap mode no parameters are used. The autovacuum launcher process * doesn't use any parameters either, because it only goes far enough to be * able to read pg_database; it doesn't connect to any particular database. * In walsender mode only username is used. * * As of PostgreSQL 8.2, we expect init_process() was already called, so we * already have a struct proc struct ... but it's not completely filled in yet. * * Note: * Be very careful with the order of calls in the init_postgres function. * -------------------------------- */ void init_postgres(const char *in_dbname, oid_t dboid, const char *username, char *out_dbname) { bool bootstrap = BOOTSTRAP_MODE(); bool am_superuser; char *fullpath; char dbname[NAMEDATALEN]; elog(DEBUG3, "init_postgres"); /* * Add my struct proc struct to the ProcArray. * * Once I have done this, I am visible to other backends! */ init_proc_phase2(); /* * Initialize my entry in the shared-invalidation manager's array of * per-backend data. * * Sets up current_bid, a unique backend identifier. */ current_bid = INVALID_BKNID; sci_bkn_init(false); if (current_bid > MAX_NR_BACKENDS || current_bid <= 0) elog(FATAL, "bad backend ID: %d", current_bid); /* Now that we have a bid_t, we can participate in ProcSignal */ signal_init(current_bid); /* * bufmgr needs another initialization call too */ init_buffer_pool_bkn(); /* * Initialize local process's access to XLOG. */ if (child) { /* * The postmaster already started the XLOG machinery, but we need to * call init_xlog_access(), if the system isn't in hot-standby mode. * This is handled by calling recovery_in_progres and ignoring the * result. */ (void) recovery_in_progres(); } else { /* * We are either a bootstrap process or a standalone backend. Either * way, start up the XLOG machinery, and register to have it closed * down at exit. */ startup_xlog(); on_shmem_exit(shutdown_xlog, 0); } /* * Initialize the relation cache and the system catalog caches. Note that * no catalog access happens here; we only set up the hashtable structure. * We must do this before starting a transaction because transaction abort * would try to touch these hashtables. */ relcache_init_phase1(); init_catcache_phase1(); init_plan_cache(); /* Initialize portal manager */ start_portal(); /* Initialize stats collection --- must happen before first xact */ if (!bootstrap) stat_init(); /* * Load relcache entries for the shared system catalogs. This must * create at least entries for pg_database and catalogs used for * authentication. */ relcache_init_phase2(); /* * Set up process-exit callback to do pre-shutdown cleanup. This has to * be after we've initialized all the low-level modules like the buffer * manager, because during shutdown this has to run before the low-level * modules start to close down. On the other hand, we want it in place * before we begin our first transaction --- if we fail during the * initialization transaction, as is entirely possible, we need the * AbortTransaction call to clean up. */ on_shmem_exit(ShutdownPostgres, 0); /* The autovacuum launcher is done here */ if (is_avl_proc()) return; /* * Start a new transaction here before first access to db, and get a * snapshot. We don't have a use for the snapshot itself, but we're * interested in the secondary effect that it sets recent_global_xmin. (This * is critical for anything that reads heap pages, because HOT may decide * to prune them even if the process doesn't attempt to modify any * tuples.) */ if (!bootstrap) { /* statement_timestamp must be set for timeouts to work correctly */ set_current_stmt_start(); start_xact_cmd(); (void) get_xact_snap(); } /* * Perform client authentication if necessary, then figure out our * postgres user ID, and see if we are a superuser. * * In standalone mode and in autovacuum worker processes, we use a fixed * ID, otherwise we figure it out from the authenticated user name. */ if (bootstrap || is_avw_proc()) { init_session_uidStandalone(); am_superuser = true; } else if (!child) { init_session_uidStandalone(); am_superuser = true; if (!ThereIsAtLeastOneRole()) ereport(WARNING, ( errcode(E_UNDEFINED_OBJECT), errmsg("no roles are defined in this database system"), errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.", username))); } else { /* normal multiuser case */ ASSERT(proc_port != NULL); PerformAuthentication(proc_port); init_session_uid(username); am_superuser = superuser(); } /* * If we're trying to shut down, only superusers can connect, and new * replication connections are not allowed. */ if ((!am_superuser || am_walsender) && proc_port != NULL && proc_port->canAcceptConnections == CAC_WAITBACKUP) { if (am_walsender) ereport(FATAL, ( errcode(E_INSUFFICIENT_PRIVILEGE), errmsg("new replication connections are not allowed during database shutdown"))); else ereport(FATAL, ( errcode(E_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to connect during database shutdown"))); } /* * Binary upgrades only allowed super-user connections */ if (is_binary_upgrade && !am_superuser) { ereport(FATAL, ( errcode(E_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to connect in binary upgrade mode"))); } /* * The last few connections slots are reserved for superusers. Although * replication connections currently require superuser privileges, we * don't allow them to consume the reserved slots, which are intended for * interactive use. */ if ((!am_superuser || am_walsender) && reserved_bknds > 0 && !have_nfree_procs(reserved_bknds)) ereport(FATAL, ( errcode(E_TOO_MANY_CONNECTIONS), errmsg("remaining connection slots are reserved for non-replication superuser connections"))); /* * If walsender, we don't want to connect to any particular database. Just * finish the backend startup by processing any options from the startup * packet, and we're done. */ if (am_walsender) { ASSERT(!bootstrap); /* must have authenticated as a replication role */ if (!is_authenticated_user_replication_role()) ereport(FATAL, ( errcode(E_INSUFFICIENT_PRIVILEGE), errmsg("must be replication role to start walsender"))); /* process any options passed in the startup packet */ if (proc_port != NULL) process_startup_options(proc_port, am_superuser); /* Apply post_auth_delay as soon as we've read all options */ if (post_auth_delay > 0) pg_usleep(post_auth_delay * 1000000L); /* initialize client encoding */ init_client_encoding(); /* report this backend in the struct backend_status array */ stat_backend_start(); /* close the transaction we started above */ commit_xact_cmd(); return; } /* * Set up the global variables holding database id and default tablespace. * But note we won't actually try to touch the database just yet. * * We take a shortcut in the bootstrap case, otherwise we have to look up * the db's entry in pg_database. */ if (bootstrap) { current_db_id = TemplateDbOid; current_tbs_id = DEFAULT_TBS_OID; } else if (in_dbname != NULL) { struct heap_tuple *tuple; Form_pg_database dbform; tuple = GetDatabaseTuple(in_dbname); if (!HT_VALID(tuple)) ereport(FATAL, ( errcode(E_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", in_dbname))); dbform = (Form_pg_database) GET_STRUCT(tuple); current_db_id = HEAPTUP_OID(tuple); current_tbs_id = dbform->dattablespace; /* take database name from the caller, just for paranoia */ strlcpy(dbname, in_dbname, sizeof(dbname)); } else { /* caller specified database by OID */ struct heap_tuple *tuple; Form_pg_database dbform; tuple = GetDatabaseTupleByOid(dboid); if (!HT_VALID(tuple)) { ereport(FATAL, ( errcode(E_UNDEFINED_DATABASE), errmsg("database %u does not exist", dboid))); } dbform = (Form_pg_database) GET_STRUCT(tuple); current_db_id = HEAPTUP_OID(tuple); current_tbs_id = dbform->dattablespace; ASSERT(current_db_id == dboid); strlcpy(dbname, NAME_TO_STR(dbform->datname), sizeof(dbname)); /* pass the database name back to the caller */ if (out_dbname) strcpy(out_dbname, dbname); } /* Now we can mark our struct proc entry with the database ID */ /* (We assume this is an atomic store so no lock is needed) */ current_proc->databaseId = current_db_id; /* * Now, take a writer's lock on the database we are trying to connect to. * If there is a concurrently running DROP DATABASE on that database, this * will block us until it finishes (and has committed its update of * pg_database). * * Note that the lock is not held long, only until the end of this startup * transaction. This is OK since we are already advertising our use of * the database in the struct proc array; anyone trying a DROP DATABASE after * this point will see us there. * * Note: use of ROW_EXCL_LOCK here is reasonable because we envision * our session as being a concurrent writer of the database. If we had a * way of declaring a session as being guaranteed-read-only, we could use * ACCESS_SHR_LOCK for such sessions and thereby not conflict against * CREATE DATABASE. */ if (!bootstrap) lock_sobj(DatabaseRelationId, current_db_id, 0, ROW_EXCL_LOCK); /* * Recheck pg_database to make sure the target database hasn't gone away. * If there was a concurrent DROP DATABASE, this ensures we will die * cleanly without creating a mess. */ if (!bootstrap) { struct heap_tuple *tuple; tuple = GetDatabaseTuple(dbname); if (!HT_VALID(tuple) || current_db_id != HEAPTUP_OID(tuple) || current_tbs_id != ((Form_pg_database) GET_STRUCT(tuple))->dattablespace) ereport(FATAL, ( errcode(E_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", dbname), errdetail("It seems to have just been dropped or renamed."))); } /* * Now we should be able to access the database directory safely. Verify * it's there and looks reasonable. */ fullpath = get_db_path(current_db_id, current_tbs_id); if (!bootstrap) { if (access(fullpath, F_OK) == -1) { if (errno == ENOENT) { ereport(FATAL, ( errcode(E_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", dbname), errdetail("The database subdirectory \"%s\" is missing.", fullpath))); } else { ereport(FATAL, ( errcode_file_access(), errmsg("could not access directory \"%s\": %m", fullpath))); } } check_version(fullpath); } set_db_path(fullpath); /* * It's now possible to do real access to the system catalogs. * * Load relcache entries for the system catalogs. This must create at * least the minimum set of "nailed-in" cache entries. */ relcache_init_phase3(); /* set up ACL framework (so CheckMyDatabase can check permissions) */ initialize_acl(); /* * Re-read the pg_database row for our database, check permissions and set * up database-specific GUC settings. We can't do this until all the * database-access infrastructure is up. (Also, it wants to know if the * user is a superuser, so the above stuff has to happen first.) */ if (!bootstrap) CheckMyDatabase(dbname, am_superuser); /* * Now process any command-line switches and any additional GUC variable * settings passed in the startup packet. We couldn't do this before * because we didn't know if client is a superuser. */ if (proc_port != NULL) process_startup_options(proc_port, am_superuser); /* Process pg_db_role_setting options */ process_settings(current_db_id, get_session_uid()); /* Apply post_auth_delay as soon as we've read all options */ if (post_auth_delay > 0) pg_usleep(post_auth_delay * 1000000L); /* * Initialize various default states that can't be set up until we've * selected the active user and gotten the right GUC settings. */ /* set default namespace search path */ init_search_path(); /* initialize client encoding */ init_client_encoding(); /* report this backend in the struct backend_status array */ if (!bootstrap) stat_backend_start(); /* close the transaction we started above */ if (!bootstrap) commit_xact_cmd(); }
/* check filesystem against extra mtree data if available, * NOT guaranteed to catch db/filesystem discrepencies */ static int check_file_properties(alpm_pkg_t *pkg) { char path[PATH_MAX], *rel; int ret = 0; size_t space; struct archive *mtree = alpm_pkg_mtree_open(pkg); struct archive_entry *entry; if(!mtree) { pu_ui_warn("%s: mtree data not available (%s)", alpm_pkg_get_name(pkg), strerror(errno)); return require_mtree; } strncpy(path, alpm_option_get_root(handle), PATH_MAX); rel = path + strlen(path); space = PATH_MAX - (rel - path); while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) { const char *ppath = archive_entry_pathname(entry); const char *fpath; struct stat buf; if(strncmp("./", ppath, 2) == 0) { ppath += 2; } if(strcmp(ppath, ".INSTALL") == 0) { if((fpath = get_db_path(pkg, "install")) == NULL) { continue; } } else if(strcmp(ppath, ".CHANGELOG") == 0) { if((fpath = get_db_path(pkg, "changelog")) == NULL) { continue; } } else if(ppath[0] == '.') { continue; } else if(skip_noextract && match_noextract(handle, ppath)) { continue; } else { strncpy(rel, ppath, space); fpath = path; } if(lstat(fpath, &buf) != 0) { if(errno == ENOENT) { eprintf("%s: '%s' missing file\n", alpm_pkg_get_name(pkg), fpath); } else { pu_ui_warn("%s: '%s' read error (%s)", alpm_pkg_get_name(pkg), fpath, strerror(errno)); } ret = 1; continue; } if(cmp_type(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(skip_noupgrade && match_noupgrade(handle, ppath)) { continue; } if(cmp_mode(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(cmp_uid(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(cmp_gid(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(skip_backups && match_backup(pkg, ppath)) { continue; } if(S_ISLNK(buf.st_mode) && S_ISLNK(archive_entry_mode(entry))) { if(cmp_target(pkg, fpath, entry) != 0) { ret = 1; } } if(!S_ISDIR(buf.st_mode)) { if(cmp_mtime(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(!S_ISLNK(buf.st_mode)) { /* always fails for directories and symlinks */ if(cmp_size(pkg, fpath, entry, &buf) != 0) { ret = 1; } } } } alpm_pkg_mtree_close(pkg, mtree); if(!quiet && !ret) { eprintf("%s: all files match mtree\n", alpm_pkg_get_name(pkg)); } return ret; }
int main(int argc, char ** argv) { char * sep; sqlite3 * db = NULL; struct Package current = blank_package; char baseurl[256] = ""; char line[sizeof(current.homepage)]; /* No line will be larger than the largest field */ int code; int chained_call = 0; char * db_path = NULL; /* NOTE: If Package ever contains varible fields, this must be changed */ char sql[sizeof(current) + 8*3*sizeof(char) + 137*sizeof(char) + 256*sizeof(char)]; while((code = getopt(argc, argv, "schd:")) != -1) { switch(code) { case 's': if(db != NULL) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } print_sql = 1; break; case 'c': chained_call = 1; break; case 'h': help(); break; case 'd': if(print_sql) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } if(sqlite3_open(optarg, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } break; default: help(); } } /* Open database */ if(!print_sql && db == NULL && (db_path = get_db_path()) && sqlite3_open(db_path, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } if(db_path) { free(db_path); } /* Do everything as one transaction. Many times faster */ safe_execute(db, "BEGIN TRANSACTION;"); /* Create tables if they do not exist */ safe_execute(db, "CREATE TABLE IF NOT EXISTS packages " \ "(package TEXT PRIMARY KEY, name TEXT, version TEXT," \ "maintainer TEXT, installed_size INTEGER, size INTEGER," \ "homepage TEXT, section TEXT, category TEXT, baseurl TEXT,"\ "path TEXT, md5 TEXT, description TEXT, user_rating INTEGER,"\ "user_owns TEXT, status INTEGER, rating INTEGER, price INTEGER);" \ "CREATE TABLE IF NOT EXISTS virtual_packages (package TEXT PRIMARY KEY, is_really TEXT);" \ "CREATE TABLE IF NOT EXISTS depends (package TEXT, depend TEXT, version TEXT);" ); if(!chained_call) { safe_execute(db, "DELETE FROM virtual_packages;"); safe_execute(db, "DELETE FROM depends;"); } /* Loop over lines from stream */ code = 0; while(fgets(line, sizeof(line), stdin)) { if(line[0] == '#') { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } strncpy(baseurl, line + 1, sizeof(baseurl)-1); /* Blank line means end of this package definition */ } else if(line[0] == '\n') { current.baseurl = baseurl; if(current.package[0] != '\0') { package_insert_sql(¤t, sql, sizeof(sql)); if(print_sql) { puts(sql); } else { if((code = sqlite3_exec(db, sql, NULL, NULL, NULL)) != 0) { if(code == SQLITE_CONSTRAINT) { package_update_sql(¤t, sql, sizeof(sql)); safe_execute(db, sql); } else { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } } } } /* Reset things */ code = 0; current = blank_package; } else { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } /* Description spans multiple lines at the end, concat stuff */ if(code) { strncat(current.description, "\n", sizeof(current.description)-1); strncat(current.description, line, sizeof(current.description)-1); } else { /* Split on colon */ if((sep = strchr(line, ':'))) { *sep = '\0'; /* Skip over the space too */ sep = sep + 2; /* If we haven't seen the field yet, do a string compare to see if * this is it. Copy remainder of line into struct */ if( current.package[0] == '\0' && strcmp(line, "Package") == 0) { strncpy(current.package, sep, sizeof(current.package)-1); } else if(current.name[0] == '\0' && strcmp(line, "Name") == 0) { strncpy(current.name, sep, sizeof(current.name)-1); } else if(current.category[0] == '\0' && strcmp(line, "Category") == 0) { strncpy(current.category, sep, sizeof(current.category)-1); } else if(current.version[0] == '\0' && strcmp(line, "Version") == 0) { strncpy(current.version, sep, sizeof(current.version)-1); } else if(current.user_owns[0] == '\0' && strcmp(line, "UserOwns") == 0) { strncpy(current.user_owns, sep, sizeof(current.user_owns)-1); } else if(current.section[0] == '\0' && strcmp(line, "Section") == 0) { strncpy(current.section, sep, sizeof(current.section)-1); } else if(current.md5[0] == '\0' && strcmp(line, "MD5sum") == 0) { strncpy(current.md5, sep, sizeof(current.md5)-1); } else if(current.maintainer[0] == '\0' && strcmp(line, "Maintainer") == 0) { strncpy(current.maintainer, sep, sizeof(current.maintainer)-1); } else if(current.path[0] == '\0' && strcmp(line, "Filename") == 0) { strncat(current.path, sep, sizeof(current.path)-1); } else if(current.homepage == '\0' && strcmp(line, "Homepage") == 0) { strncpy(current.homepage, sep, sizeof(current.homepage)-1); } else if(current.rating == 0 && strcmp(line, "Rating") == 0) { current.rating = atoi(sep); } else if(current.user_rating == 0 && strcmp(line, "UserRating") == 0) { current.user_rating = atoi(sep); } else if(current.price == 0 && strcmp(line, "Price") == 0) { current.price = atoi(sep); } else if(current.installed_size == 0 && strcmp(line, "Installed-Size") == 0) { current.installed_size = atoi(sep); } else if(current.size == 0 && strcmp(line, "Size") == 0) { current.size = atoi(sep); } else if( strcmp(line, "Provides") == 0) { sep = strtok(sep, ", "); sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); while((sep = strtok(NULL, ", ")) != NULL) { sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); } } else if( strcmp(line, "Depends") == 0) { parse_depends(db, current.package, sep); } else if( strcmp(line, "Description") == 0) { strncpy(current.description, sep, sizeof(current.description)-1); code = 1; } } } /* if code */ } /* if line[0] == '\n' */ } /* while */ /* End the transaction only when all data has been inserted */ safe_execute(db, "END TRANSACTION;"); /* Clean up disk space */ if(!chained_call) { safe_execute(db, "DELETE FROM packages WHERE package='';"); safe_execute(db, "VACUUM;"); } /* Close database */ if(db != NULL && sqlite3_close(db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }