char* find_filesystem_credential(const char *protocol, const char *host, int port) { bool found = false; struct FileSystemCredentialKey key; struct FileSystemCredential *entry; HTAB * currentFilesystemCredentials; MemoryContext currentFilesystemCredentialsMemoryContext; get_current_credential_cache_and_memcxt(¤tFilesystemCredentials, ¤tFilesystemCredentialsMemoryContext); if (NULL == currentFilesystemCredentials) return NULL; MemoryContext old = MemoryContextSwitchTo(currentFilesystemCredentialsMemoryContext); memset(&key, 0, sizeof(key)); StrNCpy(key.protocol, protocol, sizeof(key.protocol)); StrNCpy(key.host, host, sizeof(key.host)); key.port = port; entry = (struct FileSystemCredential *) hash_search(currentFilesystemCredentials, &key, HASH_FIND, &found); MemoryContextSwitchTo(old); if (!found) return NULL; return entry->credential; }
/* * getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets * * The API of this routine differs from the standard getnameinfo() definition * in two ways: first, the addr parameter is declared as sockaddr_storage * rather than struct sockaddr, and second, the node and service fields are * guaranteed to be filled with something even on failure return. */ int getnameinfo_all(const struct sockaddr_storage * addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags) { int rc; #ifdef HAVE_UNIX_SOCKETS if (addr && addr->ss_family == AF_UNIX) rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen, node, nodelen, service, servicelen, flags); else #endif rc = getnameinfo((const struct sockaddr *) addr, salen, node, nodelen, service, servicelen, flags); if (rc != 0) { if (node) StrNCpy(node, "???", nodelen); if (service) StrNCpy(service, "???", servicelen); } return rc; }
/* * make_relative_path - make a path relative to the actual binary location * * This function exists to support relocation of installation trees. * * ret_path is the output area (must be of size MAXPGPATH) * target_path is the compiled-in path to the directory we want to find * bin_path is the compiled-in path to the directory of executables * my_exec_path is the actual location of my executable * * If target_path matches bin_path up to the last directory component of * bin_path, then we build the result as my_exec_path (less the executable * name and last directory) joined to the non-matching part of target_path. * Otherwise, we return target_path as-is. * * For example: * target_path = '/usr/local/share/postgresql' * bin_path = '/usr/local/bin' * my_exec_path = '/opt/pgsql/bin/postmaster' * Given these inputs we would return '/opt/pgsql/share/postgresql' */ static void make_relative_path(char *ret_path, const char *target_path, const char *bin_path, const char *my_exec_path) { const char *bin_end; int prefix_len; bin_end = last_dir_separator(bin_path); if (!bin_end) goto no_match; prefix_len = bin_end - bin_path + 1; if (strncmp(target_path, bin_path, prefix_len) != 0) goto no_match; StrNCpy(ret_path, my_exec_path, MAXPGPATH); trim_directory(ret_path); /* remove my executable name */ trim_directory(ret_path); /* remove last directory component (/bin) */ join_path_components(ret_path, ret_path, target_path + prefix_len); canonicalize_path(ret_path); return; no_match: StrNCpy(ret_path, target_path, MAXPGPATH); canonicalize_path(ret_path); }
void SimpleString::replace(const char* to, const char* with) { size_t c = count(to); size_t len = size(); size_t tolen = StrLen(to); size_t withlen = StrLen(with); size_t newsize = len + (withlen * c) - (tolen * c) + 1; if (newsize > 1) { char* newbuf = allocStringBuffer(newsize, __FILE__, __LINE__); for (size_t i = 0, j = 0; i < len;) { if (StrNCmp(&buffer_[i], to, tolen) == 0) { StrNCpy(&newbuf[j], with, withlen + 1); j += withlen; i += tolen; } else { newbuf[j] = buffer_[i]; j++; i++; } } deallocStringBuffer(buffer_, __FILE__, __LINE__); buffer_ = newbuf; buffer_[newsize - 1] = '\0'; } else { deallocStringBuffer(buffer_, __FILE__, __LINE__); buffer_ = getEmptyString(); } }
/* * Create a new logical slot, with invalid LSN and xid, directly. This does not * use the snapshot builder or logical decoding machinery. It's only intended * for creating a slot on a replica that mirrors the state of a slot on an * upstream master. * * Note that this is test harness code. You shouldn't expose slot internals * to SQL like this for any real world usage. See the README. */ Datum test_slot_timelines_create_logical_slot(PG_FUNCTION_ARGS) { char *slotname = text_to_cstring(PG_GETARG_TEXT_P(0)); char *plugin = text_to_cstring(PG_GETARG_TEXT_P(1)); CheckSlotRequirements(); ReplicationSlotCreate(slotname, true, RS_PERSISTENT); /* register the plugin name with the slot */ StrNCpy(NameStr(MyReplicationSlot->data.plugin), plugin, NAMEDATALEN); /* * Initialize persistent state to placeholders to be set by * test_slot_timelines_advance_logical_slot . */ MyReplicationSlot->data.xmin = InvalidTransactionId; MyReplicationSlot->data.catalog_xmin = InvalidTransactionId; MyReplicationSlot->data.restart_lsn = InvalidXLogRecPtr; MyReplicationSlot->data.confirmed_flush = InvalidXLogRecPtr; clear_slot_transient_state(); ReplicationSlotRelease(); PG_RETURN_VOID(); }
/* * MPP-220077: real_act_prefix_size should not go beyond ps_buffer_size */ void test__set_ps_display__real_act_prefix_size(void **state) { int len; ps_buffer = (char *) malloc(127 * sizeof(char)); ps_buffer_fixed_size = 79; memset(ps_buffer, 'x', ps_buffer_fixed_size * sizeof(char)); ps_buffer_size = 127; IsUnderPostmaster = true; StrNCpy(ps_host_info, "msa4000125.europe.corp.microsoft.com(57193)", sizeof(ps_host_info)); ps_host_info_size = 0; gp_session_id = 26351; Gp_role = GP_ROLE_DISPATCH; Gp_segment = -1; gp_command_count = 964; currentSliceId = -1; set_ps_display("testing activity", true); assert_true(real_act_prefix_size <= ps_buffer_size); get_real_act_ps_display(&len); assert_true(len >= 0); }
void HTTP::SplitURL(const char* url, char*& address, char*&port, char*& resource) { // Skip http:// part of url url+=7; // Find end of address part of URL const char* addressEnd=StrChr(url,':'); if (addressEnd==0) { addressEnd=StrChr(url,'/'); } if (addressEnd==0) { addressEnd=url+StrLen(url); } // Extract address address=new char[addressEnd-url+1]; StrNCpy(address,url,(int)(addressEnd-url)); address[addressEnd-url]=0; // Check if there's a port defined port=new char[StrLen(addressEnd)+5]; const char* portEnd=addressEnd; StrCpy(port,"80"); if (*addressEnd==':') { addressEnd++; portEnd=StrChr(addressEnd,'/'); if (portEnd==0) { portEnd=addressEnd+StrLen(addressEnd); } StrNCpy(port,addressEnd,(int)(portEnd-addressEnd)); port[portEnd-addressEnd]=0; } // Check if there's a resource defined resource=new char[StrLen(portEnd)+5]; StrCpy(resource,"/"); if (*portEnd=='/') { StrCpy(resource,portEnd); } }
/* * get_database_oids * * Returns a list of all database OIDs found in pg_database. */ static List * get_database_list(void) { List *dbs = NIL; Relation rel; HeapScanDesc scan; HeapTuple tup; MemoryContext resultcxt; /* This is the context that we will allocate our output data in */ resultcxt = CurrentMemoryContext; /* * Start a transaction so we can access pg_database, 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 RecentGlobalXmin. (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.) */ StartTransactionCommand(); (void) GetTransactionSnapshot(); /* We take a AccessExclusiveLock so we don't conflict with any DATABASE commands */ rel = heap_open(DatabaseRelationId, AccessExclusiveLock); scan = heap_beginscan_catalog(rel, 0, NULL); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { MemoryContext oldcxt; Form_pg_database pgdatabase = (Form_pg_database) GETSTRUCT(tup); DatabaseEntry *db_entry; /* Ignore template databases or ones that don't allow connections. */ if (pgdatabase->datistemplate || !pgdatabase->datallowconn) continue; /* * Allocate our results in the caller's context, not the * transaction's. We do this inside the loop, and restore the original * context at the end, so that leaky things like heap_getnext() are * not called in a potentially long-lived context. */ oldcxt = MemoryContextSwitchTo(resultcxt); db_entry = palloc0(sizeof(DatabaseEntry)); db_entry->oid = HeapTupleGetOid(tup); StrNCpy(NameStr(db_entry->name), NameStr(pgdatabase->datname), NAMEDATALEN); dbs = lappend(dbs, db_entry); MemoryContextSwitchTo(oldcxt); } heap_endscan(scan); heap_close(rel, AccessExclusiveLock); CommitTransactionCommand(); return dbs; }
int namestrcpy(Name name, const char *str) { if (!name || !str) return -1; StrNCpy(NameStr(*name), str, NAMEDATALEN); return 0; }
int namecpy(Name n1, Name n2) { if (!n1 || !n2) return -1; StrNCpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN); return 0; }
void deserialize_filesystem_credentials(char *binary, int len, HTAB **currentFilesystemCredentials, MemoryContext *currentFilesystemCredentialsMemoryContext) { bool found = false; struct FileSystemCredentialKey key; struct FileSystemCredential *entry; Insist(NULL != currentFilesystemCredentials); Insist(NULL != currentFilesystemCredentialsMemoryContext); Insist(NULL != binary && Gp_role == GP_ROLE_EXECUTE && len > 0); create_filesystem_credentials_internal(currentFilesystemCredentials, currentFilesystemCredentialsMemoryContext); MemoryContext old = MemoryContextSwitchTo(*currentFilesystemCredentialsMemoryContext); StringInfoData buffer; initStringInfoOfString(&buffer, binary, len); while (buffer.cursor < buffer.len) { memset(&key, 0, sizeof(key)); StrNCpy(key.host, pq_getmsgstring(&buffer), sizeof(key.host)); StrNCpy(key.protocol, pq_getmsgstring(&buffer), sizeof(key.protocol)); key.port = pq_getmsgint(&buffer, sizeof(int)); entry = (struct FileSystemCredential *) hash_search( *currentFilesystemCredentials, &key, HASH_ENTER, &found); if (found) elog(ERROR, "dispatched duplicate file system credential"); entry->credential = pstrdup(pq_getmsgstring(&buffer)); } if (buffer.cursor != buffer.len) elog(ERROR, "dispatched invalid file system credential"); MemoryContextSwitchTo(old); }
char* SimpleString::copyToNewBuffer(const char* bufferToCopy, size_t bufferSize) { if(bufferSize == 0) bufferSize = PlatformSpecificStrLen(bufferToCopy) + 1; char* newBuffer = allocStringBuffer(bufferSize); StrNCpy(newBuffer, bufferToCopy, bufferSize); newBuffer[bufferSize-1] = '\0'; return newBuffer; }
void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const { if (bufferToCopy == NULL || bufferSize == 0) return; size_t sizeToCopy = (bufferSize-1 < size()) ? bufferSize : size(); StrNCpy(bufferToCopy, buffer_, sizeToCopy); bufferToCopy[sizeToCopy] = '\0'; }
char* SimpleString::copyToNewBuffer(const char* bufferToCopy, size_t bufferSize) { if(bufferSize == 0) bufferSize = StrLen(bufferToCopy) + 1; char* newBuffer = allocStringBuffer(bufferSize, __FILE__, __LINE__); StrNCpy(newBuffer, bufferToCopy, bufferSize); newBuffer[bufferSize-1] = '\0'; return newBuffer; }
NLM_EXTERN Nlm_CharPtr LIBCALL TruncateStringCopy(char FAR *theString, Nlm_Int4 Length) /* Returns a new string consisting of at most the first length-1 characters of theString. */ { Nlm_CharPtr NewString = (Nlm_CharPtr)MemNew((size_t)Length); StrNCpy(NewString, theString, (size_t)(Length - 1)); NewString[Length-1] = NULLB; return NewString; }
/* * Start preparing a state file. * * Initializes data structure and inserts the 2PC file header record. */ void StartPrepare(GlobalTransaction gxact) { TransactionId xid = gxact->proc.xid; TwoPhaseFileHeader hdr; TransactionId *children; RelFileNode *commitrels; RelFileNode *abortrels; /* Initialize linked list */ records.head = palloc0(sizeof(XLogRecData)); records.head->buffer = InvalidBuffer; records.head->len = 0; records.head->next = NULL; records.bytes_free = Max(sizeof(TwoPhaseFileHeader), 512); records.head->data = palloc(records.bytes_free); records.tail = records.head; records.total_len = 0; /* Create header */ hdr.magic = TWOPHASE_MAGIC; hdr.total_len = 0; /* EndPrepare will fill this in */ hdr.xid = xid; hdr.database = gxact->proc.databaseId; hdr.prepared_at = gxact->prepared_at; hdr.owner = gxact->owner; hdr.nsubxacts = xactGetCommittedChildren(&children); hdr.ncommitrels = smgrGetPendingDeletes(true, &commitrels); hdr.nabortrels = smgrGetPendingDeletes(false, &abortrels); StrNCpy(hdr.gid, gxact->gid, GIDSIZE); save_state_data(&hdr, sizeof(TwoPhaseFileHeader)); /* Add the additional info about subxacts and deletable files */ if (hdr.nsubxacts > 0) { save_state_data(children, hdr.nsubxacts * sizeof(TransactionId)); /* While we have the child-xact data, stuff it in the gxact too */ GXactLoadSubxactData(gxact, hdr.nsubxacts, children); pfree(children); } if (hdr.ncommitrels > 0) { save_state_data(commitrels, hdr.ncommitrels * sizeof(RelFileNode)); pfree(commitrels); } if (hdr.nabortrels > 0) { save_state_data(abortrels, hdr.nabortrels * sizeof(RelFileNode)); pfree(abortrels); } }
SimpleString& SimpleString::operator+=(const char* rhs) { size_t originalSize = this->size(); size_t additionalStringSize = StrLen(rhs) + 1; size_t sizeOfNewString = originalSize + additionalStringSize; char* tbuffer = copyToNewBuffer(this->buffer_, sizeOfNewString); StrNCpy(tbuffer + originalSize, rhs, additionalStringSize); deallocStringBuffer(this->buffer_, __FILE__, __LINE__); this->buffer_ = tbuffer; return *this; }
void add_filesystem_credential_to_cache(const char * uri, char *token) { char *protocol; char *host; bool found = false; struct FileSystemCredential *entry; struct FileSystemCredentialKey key; HTAB * currentFilesystemCredentials; MemoryContext currentFilesystemCredentialsMemoryContext; Assert(NULL != token); get_current_credential_cache_and_memcxt(¤tFilesystemCredentials, ¤tFilesystemCredentialsMemoryContext); Insist(NULL != currentFilesystemCredentials); Insist(NULL != currentFilesystemCredentialsMemoryContext); MemoryContext old = MemoryContextSwitchTo( currentFilesystemCredentialsMemoryContext); memset(&key, 0, sizeof(key)); if (HdfsParsePath(uri, &protocol, &host, &key.port, NULL) || NULL == protocol || NULL == host) elog(ERROR, "fail to parse uri: %s", uri); StrNCpy(key.protocol, protocol, sizeof(key.protocol)); StrNCpy(key.host, host, sizeof(key.host)); entry = (struct FileSystemCredential *) hash_search( currentFilesystemCredentials, &key, HASH_ENTER, &found); if (!found) { entry->credential = pstrdup(token); } MemoryContextSwitchTo(old); }
static char *CopyAddress(char *pszDest, char const *pszAddr, int iSize) { char *pszDomain; if (strchr(pszAddr, '@') != NULL || (pszDomain = SysGetEnv(ENV_DEFAULT_DOMAIN)) == NULL) StrNCpy(pszDest, pszAddr, iSize); else SysSNPrintf(pszDest, iSize, "%s@%s", pszAddr, pszDomain); return pszDest; }
SimpleString::SimpleString(const char *other, size_t repeatCount) { size_t otherStringLength = StrLen(other); size_t len = otherStringLength * repeatCount + 1; buffer_ = allocStringBuffer(len, __FILE__, __LINE__); char* next = buffer_; for (size_t i = 0; i < repeatCount; i++) { StrNCpy(next, other, otherStringLength + 1); next += otherStringLength; } *next = 0; }
extern CharPtr FastaTitle (BioseqPtr bsp, CharPtr pretext, CharPtr posttext) { CharPtr title = NULL; CharPtr prep, postp, predum = "", postdum = ""; Char idbuf[L_ID], defbuf[L_DEF]; Int4 prelen = 0, postlen = 0; SeqIdPtr sip; if (bsp != NULL) { if ((sip = bsp->id) != NULL) { if (pretext != NULL) { prelen = StrLen (pretext); prep = pretext; } else { prep = predum; } if (posttext != NULL) { postlen = StrLen (posttext); postp = posttext; } else { postp = postdum; } if ((title = (CharPtr) MemNew (sizeof (Char) * (L_T+prelen+postlen))) != NULL) { switch (sip->choice) { case SEQID_LOCAL: idbuf[0] = '\0'; if (sip->data.ptrvalue != NULL) StrNCpy (idbuf, ((ObjectIdPtr) sip->data.ptrvalue)->str, L_ID-1); idbuf[L_ID-1] = '\0'; break; default: FastaId (bsp, idbuf, L_ID); break; } FastaDefLine (bsp, defbuf, L_DEF, NULL, NULL, 0); sprintf (title, "%s%s %s%s", prep, idbuf, defbuf, postp); } } } return title; }
/* * Call this to update the ps status display to a fixed prefix plus an * indication of what you're currently doing passed in the argument. */ void set_ps_display(const char *activity) { #ifndef PS_USE_NONE /* no ps display for stand-alone backend */ if (!IsUnderPostmaster) return; #ifdef PS_USE_CLOBBER_ARGV /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) return; #endif /* Update ps_buffer to contain both fixed part and activity */ StrNCpy(ps_buffer + ps_buffer_fixed_size, activity, ps_buffer_size - ps_buffer_fixed_size); /* Transmit new setting to kernel, if necessary */ #ifdef PS_USE_SETPROCTITLE setproctitle("%s", ps_buffer); #endif #ifdef PS_USE_PSTAT { union pstun pst; pst.pst_command = ps_buffer; pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); } #endif /* PS_USE_PSTAT */ #ifdef PS_USE_PS_STRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = ps_buffer; #endif /* PS_USE_PS_STRINGS */ #ifdef PS_USE_CLOBBER_ARGV { int buflen; /* pad unused memory */ buflen = strlen(ps_buffer); MemSet(ps_buffer + buflen, PS_PADDING, ps_buffer_size - buflen); } #endif /* PS_USE_CLOBBER_ARGV */ #endif /* not PS_USE_NONE */ }
void abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn) { pg_time_t time = (pg_time_t) _time; struct pg_tm *tx; if (tzp != NULL) tx = pg_localtime(&time, session_timezone); else tx = pg_gmtime(&time); if (tx == NULL) elog(ERROR, "could not convert abstime to timestamp: %m"); tm->tm_year = tx->tm_year + 1900; tm->tm_mon = tx->tm_mon + 1; tm->tm_mday = tx->tm_mday; tm->tm_hour = tx->tm_hour; tm->tm_min = tx->tm_min; tm->tm_sec = tx->tm_sec; tm->tm_isdst = tx->tm_isdst; tm->tm_gmtoff = tx->tm_gmtoff; tm->tm_zone = tx->tm_zone; if (tzp != NULL) { *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ /* * XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */ if (tzn != NULL) { /* * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it * contains an error message, which doesn't fit in the buffer */ StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1); if (strlen(tm->tm_zone) > MAXTZLEN) ereport(WARNING, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid time zone name: \"%s\"", tm->tm_zone))); } } else tm->tm_isdst = -1; }
void SimpleLruInit(SlruCtl ctl, const char *name, LWLockId ctllock, const char *subdir) { SlruShared shared; bool found; shared = (SlruShared) ShmemInitStruct(name, SimpleLruShmemSize(), &found); if (!IsUnderPostmaster) { /* Initialize locks and shared memory area */ char *bufptr; int slotno; Assert(!found); memset(shared, 0, sizeof(SlruSharedData)); shared->ControlLock = ctllock; bufptr = (char *) shared + BUFFERALIGN(sizeof(SlruSharedData)); for (slotno = 0; slotno < NUM_SLRU_BUFFERS; slotno++) { shared->page_buffer[slotno] = bufptr; shared->page_status[slotno] = SLRU_PAGE_EMPTY; shared->page_lru_count[slotno] = 1; shared->buffer_locks[slotno] = LWLockAssign(); bufptr += BLCKSZ; } /* shared->latest_page_number will be set later */ } else Assert(found); /* * Initialize the unshared control struct, including directory path. We * assume caller set PagePrecedes. */ ctl->shared = shared; ctl->do_fsync = true; /* default behavior */ StrNCpy(ctl->Dir, subdir, sizeof(ctl->Dir)); }
/* * add a entry into DispatchedFilespaceDirHashTable, * replace it if already exist */ void DispatchedFilespace_AddForTablespace(Oid tablespace, const char * path) { bool found; DispatchedFilespaceDirEntry entry; Assert(NULL != path); if (!DispatchedFilespaceDirHashTable) { DispatchedFilespace_HashTableInit(); } entry = (DispatchedFilespaceDirEntry) hash_search( DispatchedFilespaceDirHashTable, (void *) &tablespace, HASH_ENTER, &found); Assert(NULL != entry); StrNCpy(entry->location, path, FilespaceLocationBlankPaddedWithNullTermLen); }
/* * Wrapper around strerror and strerror_r to use the former if it is * available and also return a more useful value (the error string). */ char * pqStrerror(int errnum, char *strerrbuf, size_t buflen) { #if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_STRERROR_R) /* reentrant strerror_r is available */ #ifdef STRERROR_R_INT /* SUSv3 version */ if (strerror_r(errnum, strerrbuf, buflen) == 0) return strerrbuf; else return "Unknown error"; #else /* GNU libc */ return strerror_r(errnum, strerrbuf, buflen); #endif #else /* no strerror_r() available, just use strerror */ StrNCpy(strerrbuf, strerror(errnum), buflen); return strerrbuf; #endif }
/* * join_path_components - join two path components, inserting a slash * * ret_path is the output area (must be of size MAXPGPATH) * * ret_path can be the same as head, but not the same as tail. */ void join_path_components(char *ret_path, const char *head, const char *tail) { if (ret_path != head) StrNCpy(ret_path, head, MAXPGPATH); /* * Remove any leading "." and ".." in the tail component, * adjusting head as needed. */ for (;;) { if (tail[0] == '.' && IS_DIR_SEP(tail[1])) { tail += 2; } else if (tail[0] == '.' && tail[1] == '\0') { tail += 1; break; } else if (tail[0] == '.' && tail[1] == '.' && IS_DIR_SEP(tail[2])) { trim_directory(ret_path); tail += 3; } else if (tail[0] == '.' && tail[1] == '.' && tail[2] == '\0') { trim_directory(ret_path); tail += 2; break; } else break; } if (*tail) snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path), "/%s", tail); }
/* * get_home_path * * On Unix, this actually returns the user's home directory. On Windows * it returns the PostgreSQL-specific application data folder. */ bool get_home_path(char *ret_path) { #ifndef WIN32 char pwdbuf[BUFSIZ]; struct passwd pwdstr; struct passwd *pwd = NULL; if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0) return false; StrNCpy(ret_path, pwd->pw_dir, MAXPGPATH); return true; #else char tmppath[MAX_PATH]; ZeroMemory(tmppath, sizeof(tmppath)); if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK) return false; snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath); return true; #endif }
int main(int argc, char *argv[]) { char *pghost = NULL; char *pgport = NULL; char *pguser = NULL; bool force_password = false; bool data_only = false; bool globals_only = false; bool schema_only = false; PGconn *conn; int c, ret; static struct option long_options[] = { {"data-only", no_argument, NULL, 'a'}, {"clean", no_argument, NULL, 'c'}, {"inserts", no_argument, NULL, 'd'}, {"attribute-inserts", no_argument, NULL, 'D'}, {"column-inserts", no_argument, NULL, 'D'}, {"globals-only", no_argument, NULL, 'g'}, {"host", required_argument, NULL, 'h'}, {"ignore-version", no_argument, NULL, 'i'}, {"oids", no_argument, NULL, 'o'}, {"no-owner", no_argument, NULL, 'O'}, {"port", required_argument, NULL, 'p'}, {"password", no_argument, NULL, 'W'}, {"schema-only", no_argument, NULL, 's'}, {"superuser", required_argument, NULL, 'S'}, {"username", required_argument, NULL, 'U'}, {"verbose", no_argument, NULL, 'v'}, {"no-privileges", no_argument, NULL, 'x'}, {"no-acl", no_argument, NULL, 'x'}, /* * the following options don't have an equivalent short option letter, * but are available as '-X long-name' */ {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {NULL, 0, NULL, 0} }; int optindex; set_pglocale_pgservice(argv[0], "pg_dump"); progname = get_progname(argv[0]); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_dumpall (PostgreSQL) " PG_VERSION); exit(0); } } if ((ret = find_other_exec(argv[0], "pg_dump", PG_VERSIONSTR, pg_dump_bin)) < 0) { char full_path[MAXPGPATH]; if (find_my_exec(argv[0], full_path) < 0) StrNCpy(full_path, progname, MAXPGPATH); if (ret == -1) fprintf(stderr, _("The program \"pg_dump\" is needed by %s " "but was not found in the\n" "same directory as \"%s\".\n" "Check your installation.\n"), progname, full_path); else fprintf(stderr, _("The program \"pg_dump\" was found by \"%s\"\n" "but was not the same version as %s.\n" "Check your installation.\n"), full_path, progname); exit(1); } pgdumpopts = createPQExpBuffer(); while ((c = getopt_long(argc, argv, "acdDgh:ioOp:sS:U:vWxX:", long_options, &optindex)) != -1) { switch (c) { case 'a': data_only = true; appendPQExpBuffer(pgdumpopts, " -a"); break; case 'c': output_clean = true; break; case 'd': case 'D': appendPQExpBuffer(pgdumpopts, " -%c", c); break; case 'g': globals_only = true; break; case 'h': pghost = optarg; #ifndef WIN32 appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost); #else appendPQExpBuffer(pgdumpopts, " -h \"%s\"", pghost); #endif break; case 'i': ignoreVersion = true; appendPQExpBuffer(pgdumpopts, " -i"); break; case 'o': appendPQExpBuffer(pgdumpopts, " -o"); break; case 'O': appendPQExpBuffer(pgdumpopts, " -O"); break; case 'p': pgport = optarg; #ifndef WIN32 appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport); #else appendPQExpBuffer(pgdumpopts, " -p \"%s\"", pgport); #endif break; case 's': schema_only = true; appendPQExpBuffer(pgdumpopts, " -s"); break; case 'S': #ifndef WIN32 appendPQExpBuffer(pgdumpopts, " -S '%s'", optarg); #else appendPQExpBuffer(pgdumpopts, " -S \"%s\"", optarg); #endif break; case 'U': pguser = optarg; #ifndef WIN32 appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser); #else appendPQExpBuffer(pgdumpopts, " -U \"%s\"", pguser); #endif break; case 'v': verbose = true; appendPQExpBuffer(pgdumpopts, " -v"); break; case 'W': force_password = true; appendPQExpBuffer(pgdumpopts, " -W"); break; case 'x': skip_acls = true; appendPQExpBuffer(pgdumpopts, " -x"); break; case 'X': if (strcmp(optarg, "disable-dollar-quoting") == 0) appendPQExpBuffer(pgdumpopts, " -X disable-dollar-quoting"); else if (strcmp(optarg, "disable-triggers") == 0) appendPQExpBuffer(pgdumpopts, " -X disable-triggers"); else if (strcmp(optarg, "use-set-session-authorization") == 0) /* no-op, still allowed for compatibility */ ; else { fprintf(stderr, _("%s: invalid -X option -- %s\n"), progname, optarg); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } break; case 0: break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } /* Add long options to the pg_dump argument list */ if (disable_dollar_quoting) appendPQExpBuffer(pgdumpopts, " -X disable-dollar-quoting"); if (disable_triggers) appendPQExpBuffer(pgdumpopts, " -X disable-triggers"); if (use_setsessauth) appendPQExpBuffer(pgdumpopts, " -X use-set-session-authorization"); if (optind < argc) { fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } /* * First try to connect to database "postgres", and failing that * "template1". "postgres" is the preferred choice for 8.1 and later * servers, but it usually will not exist on older ones. */ conn = connectDatabase("postgres", pghost, pgport, pguser, force_password, false); if (!conn) conn = connectDatabase("template1", pghost, pgport, pguser, force_password, true); printf("--\n-- PostgreSQL database cluster dump\n--\n\n"); if (verbose) dumpTimestamp("Started on"); printf("\\connect postgres\n\n"); if (!data_only) { /* Dump roles (users) */ dumpRoles(conn); /* Dump role memberships --- need different method for pre-8.1 */ if (server_version >= 80100) dumpRoleMembership(conn); else dumpGroups(conn); /* Dump tablespaces */ if (server_version >= 80000) dumpTablespaces(conn); /* Dump CREATE DATABASE commands */ if (!globals_only) dumpCreateDB(conn); } if (!globals_only) dumpDatabases(conn); PQfinish(conn); if (verbose) dumpTimestamp("Completed on"); printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n"); exit(0); }
/* * find_my_exec -- find an absolute path to a valid executable * * argv0 is the name passed on the command line * retpath is the output area (must be of size MAXPGPATH) * Returns 0 if OK, -1 if error. * * The reason we have to work so hard to find an absolute path is that * on some platforms we can't do dynamic loading unless we know the * executable's location. Also, we need a full path not a relative * path because we will later change working directory. Finally, we want * a true path not a symlink location, so that we can locate other files * that are part of our installation relative to the executable. * * This function is not thread-safe because it calls validate_exec(), * which calls getgrgid(). This function should be used only in * non-threaded binaries, not in library routines. */ int find_my_exec(const char *argv0, char *retpath) { char cwd[MAXPGPATH], test_path[MAXPGPATH]; char *path; if (!getcwd(cwd, MAXPGPATH)) { log_error(_("could not identify current directory: %s"), strerror(errno)); return -1; } /* * If argv0 contains a separator, then PATH wasn't used. */ if (first_dir_separator(argv0) != NULL) { if (is_absolute_path(argv0)) StrNCpy(retpath, argv0, MAXPGPATH); else join_path_components(retpath, cwd, argv0); canonicalize_path(retpath); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); log_error(_("invalid binary \"%s\""), retpath); return -1; } #ifdef WIN32 /* Win32 checks the current directory first for names without slashes */ join_path_components(retpath, cwd, argv0); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); #endif /* * Since no explicit path was supplied, the user must have been relying on * PATH. We'll search the same PATH. */ if ((path = getenv("PATH")) && *path) { char *startp = NULL, *endp = NULL; do { if (!startp) startp = path; else startp = endp + 1; endp = first_path_separator(startp); if (!endp) endp = startp + strlen(startp); /* point to end */ StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH)); if (is_absolute_path(test_path)) join_path_components(retpath, test_path, argv0); else { join_path_components(retpath, cwd, test_path); join_path_components(retpath, retpath, argv0); } canonicalize_path(retpath); switch (validate_exec(retpath)) { case 0: /* found ok */ return resolve_symlinks(retpath); case -1: /* wasn't even a candidate, keep looking */ break; case -2: /* found but disqualified */ log_error(_("could not read binary \"%s\""), retpath); break; } } while (*endp); } log_error(_("could not find a \"%s\" to execute"), argv0); return -1; }