int main(int argc, char *argv[]) { static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; char *DataDir = NULL; int c; int option_index; bool crc_ok; set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_checksums")); progname = get_progname(argv[0]); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_checksums (PostgreSQL) " PG_VERSION); exit(0); } } while ((c = getopt_long(argc, argv, "D:r:v", long_options, &option_index)) != -1) { switch (c) { case 'v': verbose = true; break; case 'D': DataDir = optarg; break; case 'r': if (atoi(optarg) == 0) { fprintf(stderr, _("%s: invalid relfilenode specification, must be numeric: %s\n"), progname, optarg); exit(1); } only_relfilenode = pstrdup(optarg); break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } if (DataDir == NULL) { if (optind < argc) DataDir = argv[optind++]; else DataDir = getenv("PGDATA"); /* If no DataDir was specified, and none could be found, error out */ if (DataDir == NULL) { fprintf(stderr, _("%s: no data directory specified\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } /* Complain if any arguments remain */ 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); } /* Check if cluster is running */ ControlFile = get_controlfile(DataDir, progname, &crc_ok); if (!crc_ok) { fprintf(stderr, _("%s: pg_control CRC value is incorrect\n"), progname); exit(1); } if (ControlFile->pg_control_version != PG_CONTROL_VERSION) { fprintf(stderr, _("%s: cluster is not compatible with this version of pg_checksums\n"), progname); exit(1); } if (ControlFile->state != DB_SHUTDOWNED && ControlFile->state != DB_SHUTDOWNED_IN_RECOVERY) { fprintf(stderr, _("%s: cluster must be shut down to verify checksums\n"), progname); exit(1); } if (ControlFile->data_checksum_version == 0) { fprintf(stderr, _("%s: data checksums are not enabled in cluster\n"), progname); exit(1); } /* Scan all files */ scan_directory(DataDir, "global"); scan_directory(DataDir, "base"); scan_directory(DataDir, "pg_tblspc"); printf(_("Checksum scan completed\n")); printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); printf(_("Files scanned: %s\n"), psprintf(INT64_FORMAT, files)); printf(_("Blocks scanned: %s\n"), psprintf(INT64_FORMAT, blocks)); printf(_("Bad checksums: %s\n"), psprintf(INT64_FORMAT, badblocks)); if (badblocks > 0) return 1; return 0; }
/* * Show oid, filenode, name, schema and tablespace for each of the * given objects in the current database. */ void sql_exec_searchtables(PGconn *conn, struct options * opts) { char *todo; char *qualifiers, *ptr; char *comma_oids, *comma_filenodes, *comma_tables; bool written = false; char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" "; /* get tables qualifiers, whether names, filenodes, or OIDs */ comma_oids = get_comma_elts(opts->oids); comma_tables = get_comma_elts(opts->tables); comma_filenodes = get_comma_elts(opts->filenodes); /* 80 extra chars for SQL expression */ qualifiers = (char *) pg_malloc(strlen(comma_oids) + strlen(comma_tables) + strlen(comma_filenodes) + 80); ptr = qualifiers; if (opts->oids->num > 0) { ptr += sprintf(ptr, "c.oid IN (%s)", comma_oids); written = true; } if (opts->filenodes->num > 0) { if (written) ptr += sprintf(ptr, " OR "); ptr += sprintf(ptr, "pg_catalog.pg_relation_filenode(c.oid) IN (%s)", comma_filenodes); written = true; } if (opts->tables->num > 0) { if (written) ptr += sprintf(ptr, " OR "); sprintf(ptr, "c.relname ~~ ANY (ARRAY[%s])", comma_tables); } free(comma_oids); free(comma_tables); free(comma_filenodes); /* now build the query */ todo = psprintf( "SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s\n" "FROM pg_catalog.pg_class c \n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n" " LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),\n" " pg_catalog.pg_tablespace t \n" "WHERE relkind IN ('r', 'm', 'i', 'S', 't') AND \n" " t.oid = CASE\n" " WHEN reltablespace <> 0 THEN reltablespace\n" " ELSE dattablespace\n" " END AND \n" " (%s) \n" "ORDER BY relname\n", opts->extended ? addfields : "", qualifiers); free(qualifiers); sql_exec(conn, todo, opts->quiet); }
Datum pg_tablespace_databases(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; struct dirent *de; ts_db_fctx *fctx; if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; Oid tablespaceOid = PG_GETARG_OID(0); funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); fctx = palloc(sizeof(ts_db_fctx)); if (tablespaceOid == GLOBALTABLESPACE_OID) { fctx->dirdesc = NULL; ereport(WARNING, (errmsg("global tablespace never has databases"))); } else { if (tablespaceOid == DEFAULTTABLESPACE_OID) fctx->location = psprintf("base"); else fctx->location = psprintf("pg_tblspc/%u/%s", tablespaceOid, TABLESPACE_VERSION_DIRECTORY); fctx->dirdesc = AllocateDir(fctx->location); if (!fctx->dirdesc) { /* the only expected error is ENOENT */ if (errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open directory \"%s\": %m", fctx->location))); ereport(WARNING, (errmsg("%u is not a tablespace OID", tablespaceOid))); } } funcctx->user_fctx = fctx; MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); fctx = (ts_db_fctx *) funcctx->user_fctx; if (!fctx->dirdesc) /* not a tablespace */ SRF_RETURN_DONE(funcctx); while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL) { Oid datOid = atooid(de->d_name); char *subdir; bool isempty; /* this test skips . and .., but is awfully weak */ if (!datOid) continue; /* if database subdir is empty, don't report tablespace as used */ subdir = psprintf("%s/%s", fctx->location, de->d_name); isempty = directory_is_empty(subdir); pfree(subdir); if (isempty) continue; /* indeed, nothing in it */ SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(datOid)); } FreeDir(fctx->dirdesc); SRF_RETURN_DONE(funcctx); }
/* * pg_be_scram_init * * Initialize a new SCRAM authentication exchange status tracker. This * needs to be called before doing any exchange. It will be filled later * after the beginning of the exchange with verifier data. * * 'selected_mech' identifies the SASL mechanism that the client selected. * It should be one of the mechanisms that we support, as returned by * pg_be_scram_get_mechanisms(). * * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword. * The username was provided by the client in the startup message, and is * available in port->user_name. If 'shadow_pass' is NULL, we still perform * an authentication exchange, but it will fail, as if an incorrect password * was given. */ void * pg_be_scram_init(Port *port, const char *selected_mech, const char *shadow_pass) { scram_state *state; bool got_verifier; state = (scram_state *) palloc0(sizeof(scram_state)); state->port = port; state->state = SCRAM_AUTH_INIT; /* * Parse the selected mechanism. * * Note that if we don't support channel binding, either because the SSL * implementation doesn't support it or we're not using SSL at all, we * would not have advertised the PLUS variant in the first place. If the * client nevertheless tries to select it, it's a protocol violation like * selecting any other SASL mechanism we don't support. */ #ifdef HAVE_BE_TLS_GET_CERTIFICATE_HASH if (strcmp(selected_mech, SCRAM_SHA_256_PLUS_NAME) == 0 && port->ssl_in_use) state->channel_binding_in_use = true; else #endif if (strcmp(selected_mech, SCRAM_SHA_256_NAME) == 0) state->channel_binding_in_use = false; else ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("client selected an invalid SASL authentication mechanism"))); /* * Parse the stored password verifier. */ if (shadow_pass) { int password_type = get_password_type(shadow_pass); if (password_type == PASSWORD_TYPE_SCRAM_SHA_256) { if (parse_scram_verifier(shadow_pass, &state->iterations, &state->salt, state->StoredKey, state->ServerKey)) got_verifier = true; else { /* * The password looked like a SCRAM verifier, but could not be * parsed. */ ereport(LOG, (errmsg("invalid SCRAM verifier for user \"%s\"", state->port->user_name))); got_verifier = false; } } else { /* * The user doesn't have SCRAM verifier. (You cannot do SCRAM * authentication with an MD5 hash.) */ state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM verifier."), state->port->user_name); got_verifier = false; } } else { /* * The caller requested us to perform a dummy authentication. This is * considered normal, since the caller requested it, so don't set log * detail. */ got_verifier = false; } /* * If the user did not have a valid SCRAM verifier, we still go through * the motions with a mock one, and fail as if the client supplied an * incorrect password. This is to avoid revealing information to an * attacker. */ if (!got_verifier) { mock_scram_verifier(state->port->user_name, &state->iterations, &state->salt, state->StoredKey, state->ServerKey); state->doomed = true; } return state; }
PDir::PDir(const pchar *dir) { // Check if the directory exists. struct stat s; if (stat(dir, &s) != 0 || !S_ISDIR(s.st_mode)) { PLOG_ERROR("%s is not a valid directory.", dir); m_exists = false; } else { m_exists = true; // Fetch the item names in that directory. DIR* dirObject; dirent* dirEntry; m_items = P_NULL; m_numberOfItems = 0; puint32 capacity = 32; puint8* itemData = PNEWARRAY(puint8, capacity * sizeof(PDirItem)); pmemset(itemData, 0, sizeof(capacity * sizeof(PDirItem))); if ((dirObject = opendir(dir)) == NULL) { PLOG_ERROR("Failed to read directory %s.", dir); PDELETEARRAY(itemData); } else { char path[4096]; while ((dirEntry = readdir(dirObject)) != NULL) { // Find first file will always return "." and ".." // as the first two directories. if (pstrcmp(dirEntry->d_name, ".") != 0 && pstrcmp(dirEntry->d_name, "..") != 0) { //Build up our file path using the passed in // [sDir] and the file/foldername we just found: psprintf(path, 4096, "%s\\%s", dir, dirEntry->d_name); //Is the entity a File or Folder? if (dirEntry->d_type == DT_DIR) { // TODO: use the absolute path. new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_DIRECTORY, path); m_numberOfItems++; } else if (dirEntry->d_type == DT_REG) { // TODO: use the absolute path. new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_FILE, path); m_numberOfItems++; } else { PLOG_WARNING("%s is not supported.", path); } if (m_numberOfItems > capacity) { resizeItemArray(itemData, capacity, 2 * capacity); capacity *= 2; } } } closedir(dirObject); //Always, Always, clean things up! m_items = reinterpret_cast<PDirItem*>(itemData); } } }
/* * Our caller already sent the query associated with this step. Wait for it * to either complete or (if given the STEP_NONBLOCK flag) to block while * waiting for a lock. We assume that any lock wait will persist until we * have executed additional steps in the permutation. * * When calling this function on behalf of a given step for a second or later * time, pass the STEP_RETRY flag. This only affects the messages printed. * * If the connection returns an error, the message is saved in step->errormsg. * Caller should call report_error_message shortly after this, to have it * printed and cleared. * * If the STEP_NONBLOCK flag was specified and the query is waiting to acquire * a lock, returns true. Otherwise, returns false. */ static bool try_complete_step(Step *step, int flags) { PGconn *conn = conns[1 + step->session]; fd_set read_set; struct timeval timeout; int sock = PQsocket(conn); int ret; PGresult *res; FD_ZERO(&read_set); while ((flags & STEP_NONBLOCK) && PQisBusy(conn)) { FD_SET(sock, &read_set); timeout.tv_sec = 0; timeout.tv_usec = 10000; /* Check for lock waits every 10ms. */ ret = select(sock + 1, &read_set, NULL, NULL, &timeout); if (ret < 0) /* error in select() */ { if (errno == EINTR) continue; fprintf(stderr, "select failed: %s\n", strerror(errno)); exit_nicely(); } else if (ret == 0) /* select() timeout: check for lock wait */ { int ntuples; res = PQexecPrepared(conns[0], PREP_WAITING, 1, &backend_pids[step->session + 1], NULL, NULL, 0); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "lock wait query failed: %s", PQerrorMessage(conn)); exit_nicely(); } ntuples = PQntuples(res); PQclear(res); if (ntuples >= 1) /* waiting to acquire a lock */ { if (!(flags & STEP_RETRY)) printf("step %s: %s <waiting ...>\n", step->name, step->sql); return true; } /* else, not waiting: give it more time */ } else if (!PQconsumeInput(conn)) /* select(): data available */ { fprintf(stderr, "PQconsumeInput failed: %s\n", PQerrorMessage(conn)); exit_nicely(); } } if (flags & STEP_RETRY) printf("step %s: <... completed>\n", step->name); else printf("step %s: %s\n", step->name, step->sql); while ((res = PQgetResult(conn))) { switch (PQresultStatus(res)) { case PGRES_COMMAND_OK: break; case PGRES_TUPLES_OK: printResultSet(res); break; case PGRES_FATAL_ERROR: if (step->errormsg != NULL) { printf("WARNING: this step had a leftover error message\n"); printf("%s\n", step->errormsg); } /* * Detail may contain XID values, so we want to just show * primary. Beware however that libpq-generated error results * may not contain subfields, only an old-style message. */ { const char *sev = PQresultErrorField(res, PG_DIAG_SEVERITY); const char *msg = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY); if (sev && msg) step->errormsg = psprintf("%s: %s", sev, msg); else step->errormsg = pg_strdup(PQresultErrorMessage(res)); } break; default: printf("unexpected result status: %s\n", PQresStatus(PQresultStatus(res))); } PQclear(res); } return false; }
/* * Actually do a base backup for the specified tablespaces. * * This is split out mainly to avoid complaints about "variable might be * clobbered by longjmp" from stupider versions of gcc. */ static void perform_base_backup(basebackup_options *opt, DIR *tblspcdir) { XLogRecPtr startptr; TimeLineID starttli; XLogRecPtr endptr; TimeLineID endtli; char *labelfile; int datadirpathlen; datadirpathlen = strlen(DataDir); backup_started_in_recovery = RecoveryInProgress(); startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli, &labelfile); /* * Once do_pg_start_backup has been called, ensure that any failure causes * us to abort the backup so we don't "leak" a backup counter. For this reason, * *all* functionality between do_pg_start_backup() and do_pg_stop_backup() * should be inside the error cleanup block! */ PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); { List *tablespaces = NIL; ListCell *lc; struct dirent *de; tablespaceinfo *ti; SendXlogRecPtrResult(startptr, starttli); /* * Calculate the relative path of temporary statistics directory in order * to skip the files which are located in that directory later. */ if (is_absolute_path(pgstat_stat_directory) && strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0) statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1); else if (strncmp(pgstat_stat_directory, "./", 2) != 0) statrelpath = psprintf("./%s", pgstat_stat_directory); else statrelpath = pgstat_stat_directory; /* Collect information about all tablespaces */ while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL) { char fullpath[MAXPGPATH]; char linkpath[MAXPGPATH]; char *relpath = NULL; int rllen; /* Skip special stuff */ if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name); #if defined(HAVE_READLINK) || defined(WIN32) rllen = readlink(fullpath, linkpath, sizeof(linkpath)); if (rllen < 0) { ereport(WARNING, (errmsg("could not read symbolic link \"%s\": %m", fullpath))); continue; } else if (rllen >= sizeof(linkpath)) { ereport(WARNING, (errmsg("symbolic link \"%s\" target is too long", fullpath))); continue; } linkpath[rllen] = '\0'; /* * Relpath holds the relative path of the tablespace directory * when it's located within PGDATA, or NULL if it's located * elsewhere. */ if (rllen > datadirpathlen && strncmp(linkpath, DataDir, datadirpathlen) == 0 && IS_DIR_SEP(linkpath[datadirpathlen])) relpath = linkpath + datadirpathlen + 1; ti = palloc(sizeof(tablespaceinfo)); ti->oid = pstrdup(de->d_name); ti->path = pstrdup(linkpath); ti->rpath = relpath ? pstrdup(relpath) : NULL; ti->size = opt->progress ? sendTablespace(fullpath, true) : -1; tablespaces = lappend(tablespaces, ti); #else /* * If the platform does not have symbolic links, it should not be * possible to have tablespaces - clearly somebody else created * them. Warn about it and ignore. */ ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("tablespaces are not supported on this platform"))); #endif } /* Add a node for the base directory at the end */ ti = palloc0(sizeof(tablespaceinfo)); ti->size = opt->progress ? sendDir(".", 1, true, tablespaces) : -1; tablespaces = lappend(tablespaces, ti); /* Send tablespace header */ SendBackupHeader(tablespaces); /* Setup and activate network throttling, if client requested it */ if (opt->maxrate > 0) { throttling_sample = (int64) opt->maxrate * (int64) 1024 / THROTTLING_FREQUENCY; /* * The minimum amount of time for throttling_sample bytes to be * transfered. */ elapsed_min_unit = USECS_PER_SEC / THROTTLING_FREQUENCY; /* Enable throttling. */ throttling_counter = 0; /* The 'real data' starts now (header was ignored). */ throttled_last = GetCurrentIntegerTimestamp(); } else { /* Disable throttling. */ throttling_counter = -1; } /* Send off our tablespaces one by one */ foreach(lc, tablespaces) { tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc); StringInfoData buf; /* Send CopyOutResponse message */ pq_beginmessage(&buf, 'H'); pq_sendbyte(&buf, 0); /* overall format */ pq_sendint(&buf, 0, 2); /* natts */ pq_endmessage(&buf); if (ti->path == NULL) { struct stat statbuf; /* In the main tar, include the backup_label first... */ sendFileWithContent(BACKUP_LABEL_FILE, labelfile); /* ... then the bulk of the files ... */ sendDir(".", 1, false, tablespaces); /* ... and pg_control after everything else. */ if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat control file \"%s\": %m", XLOG_CONTROL_FILE))); sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false); } else sendTablespace(ti->path, false); /* * If we're including WAL, and this is the main data directory we * don't terminate the tar stream here. Instead, we will append * the xlog files below and terminate it then. This is safe since * the main data directory is always sent *last*. */ if (opt->includewal && ti->path == NULL) { Assert(lnext(lc) == NULL); } else pq_putemptymessage('c'); /* CopyDone */ } }
void CMyPhoneEndPoint::LoadCapabilities() { BOOL sizeChange = FALSE; capabilities.RemoveAll(); // Add the codecs we know about AddAllCapabilities(0, 0, "*"); // Удаляю не поддерживаемые видео кодеки из реестра PINDEX videoNum = 0; for (;;) { PString key = psprintf("%u", ++videoNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = videoNum; videoNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(VideoCodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(VideoCodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(VideoCodecsConfigSection, psprintf("%u", j-1)); } } // добавляю новые видео кодеки если их нет в конфигурации for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(VideoCodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } PINDEX audioNum = 0; for (;;) { PString key = psprintf("%u", ++audioNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = audioNum; audioNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(CodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(CodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(CodecsConfigSection, psprintf("%u", j-1)); } } for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(CodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } // Add all the UserInput capabilities AddAllUserInputCapabilities(0, 1); int videoSizeRx = config.GetInteger(VideoInSizeConfigKey, 2); int videoSizeTx = config.GetInteger(VideoOutSizeConfigKey, 2); RemoveCapability(H323Capability::e_ExtendVideo); autoStartTransmitVideo = config.GetBoolean(AutoTransmitVideoConfigKey, TRUE); autoStartReceiveVideo = config.GetBoolean(AutoReceiveVideoConfigKey, TRUE); localVideo = config.GetBoolean(VideoLocalConfigKey, FALSE); localFlip = config.GetBoolean(VideoFlipLocalConfigKey, FALSE); int videoInMaxBitRate = config.GetInteger(VideoInMaxbandWidthKey, 320); videoInMaxBitRate = 1024 * PMAX(16, PMIN(10240, videoInMaxBitRate)); // changing audio codecs PStringArray enabledCodecs; PINDEX codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); enabledCodecs.AppendString(name); } codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; } int tvNum = 0; // if(tvCaps==NULL) this generates error in free tvCaps = (char **)calloc(codecNum+1,sizeof(char *)); // while(tvCaps[tvNum]!=NULL) { free(tvCaps[tvNum]); tvCaps[tvNum]=NULL; tvNum++; } tvNum = 0; codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; // удаление отключенных кодеков PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } // удаление суффикса on из имени кодека suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); // проверка кодека на соответствие размеру принимаемой картинки // (меньше можно, больше нельзя) и удаление из списка локальных кодеков suffixPos = P_MAX_INDEX; switch(videoSizeRx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; case 7: //SXGA suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 8: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) enabledCodecs.AppendString(name); else capabilities.Remove(name); // проверка кодека на соответствие размеру отправляемой картинки // (меньше можно, больше нельзя) и создание списка допустимых кодеков suffixPos = P_MAX_INDEX; switch(videoSizeTx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; case 7: //HD 720 suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 8: //SXGA suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 9: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) // добавляю в список допустимых { const char *p2pstr=name; tvCaps[tvNum]=strdup(p2pstr); tvNum++; } } // Reorder the codecs we have capabilities.Reorder(enabledCodecs); for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { capabilities[i].SetMediaFormatOptionInteger(OpalVideoFormat::MaxBitRateOption, videoInMaxBitRate); if((capabilities[i].GetFormatName().Find("H.264")!=P_MAX_INDEX) || (capabilities[i].GetFormatName().Find("VP8-")==0)) { H323GenericVideoCapability *h264cap = (H323GenericVideoCapability *) &capabilities[i]; h264cap->SetMaxBitRate(videoInMaxBitRate/100); } } } /* PINDEX audioNum = 1; PINDEX videoNum = 1; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { config.SetString(CodecsConfigSection, psprintf("%u", audioNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } else if (capabilities[i].GetMainType() == H323Capability::e_Video) { config.SetString(VideoCodecsConfigSection, psprintf("%u", videoNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } } */ PTRACE(1, "MyPhone\tCapability Table:\n" << setprecision(4) << capabilities); }
Datum pg_control_checkpoint(PG_FUNCTION_ARGS) { Datum values[19]; bool nulls[19]; TupleDesc tupdesc; HeapTuple htup; ControlFileData *ControlFile; XLogSegNo segno; char xlogfilename[MAXFNAMELEN]; bool crc_ok; /* * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ tupdesc = CreateTemplateTupleDesc(18); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn", LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn", LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes", BOOLOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time", TIMESTAMPTZOID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); /* Read the control file. */ ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) ereport(ERROR, (errmsg("calculated CRC checksum does not match value stored in file"))); /* * Calculate name of the WAL file containing the latest checkpoint's REDO * start point. */ XLByteToSeg(ControlFile->checkPointCopy.redo, segno, wal_segment_size); XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID, segno, wal_segment_size); /* Populate the values and null arrays */ values[0] = LSNGetDatum(ControlFile->checkPoint); nulls[0] = false; values[1] = LSNGetDatum(ControlFile->checkPointCopy.redo); nulls[1] = false; values[2] = CStringGetTextDatum(xlogfilename); nulls[2] = false; values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID); nulls[3] = false; values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID); nulls[4] = false; values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites); nulls[5] = false; values[6] = CStringGetTextDatum(psprintf("%u:%u", EpochFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid), XidFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid))); nulls[6] = false; values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid); nulls[7] = false; values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti); nulls[8] = false; values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset); nulls[9] = false; values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid); nulls[10] = false; values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB); nulls[11] = false; values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid); nulls[12] = false; values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti); nulls[13] = false; values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB); nulls[14] = false; values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid); nulls[15] = false; values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid); nulls[16] = false; values[17] = TimestampTzGetDatum( time_t_to_timestamptz(ControlFile->checkPointCopy.time)); nulls[17] = false; htup = heap_form_tuple(tupdesc, values, nulls); PG_RETURN_DATUM(HeapTupleGetDatum(htup)); }
/* * start a psql test process for specified file (including redirection), * and return process ID */ static PID_TYPE psql_start_test(const char *testname, _stringlist **resultfiles, _stringlist **expectfiles, _stringlist **tags) { PID_TYPE pid; char infile[MAXPGPATH]; char outfile[MAXPGPATH]; char expectfile[MAXPGPATH]; char psql_cmd[MAXPGPATH * 3]; size_t offset = 0; char *appnameenv; /* * Look for files in the output dir first, consistent with a vpath search. * This is mainly to create more reasonable error messages if the file is * not found. It also allows local test overrides when running pg_regress * outside of the source tree. */ snprintf(infile, sizeof(infile), "%s/sql/%s.sql", outputdir, testname); if (!file_exists(infile)) snprintf(infile, sizeof(infile), "%s/sql/%s.sql", inputdir, testname); snprintf(outfile, sizeof(outfile), "%s/results/%s.out", outputdir, testname); snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out", outputdir, testname); if (!file_exists(expectfile)) snprintf(expectfile, sizeof(expectfile), "%s/expected/%s.out", inputdir, testname); add_stringlist_item(resultfiles, outfile); add_stringlist_item(expectfiles, expectfile); if (launcher) offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, "%s ", launcher); appnameenv = psprintf("PGAPPNAME=pg_regress/%s", testname); putenv(appnameenv); snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, "\"%s%spsql\" -X -a -q -d \"%s\" < \"%s\" > \"%s\" 2>&1", bindir ? bindir : "", bindir ? "/" : "", dblist->str, infile, outfile); pid = spawn_process(psql_cmd); if (pid == INVALID_PID) { fprintf(stderr, _("could not start process for test %s\n"), testname); exit(2); } unsetenv("PGAPPNAME"); free(appnameenv); return pid; }
/* Get authority (host:port) for the PXF server URL */ char * get_authority(void) { return psprintf("%s:%d", get_pxf_host(), get_pxf_port()); }
/* ------------------------------------------------ * bt_metap() * * Get a btree's meta-page information * * Usage: SELECT * FROM bt_metap('t1_pkey') * ------------------------------------------------ */ Datum bt_metap(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_PP(0); Datum result; Relation rel; RangeVar *relrv; BTMetaPageData *metad; TupleDesc tupleDesc; int j; char *values[6]; Buffer buffer; Page page; HeapTuple tuple; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pageinspect functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", RelationGetRelationName(rel)); /* * Reject attempts to read non-local temporary relations; we would be * likely to get wrong data since we have no visibility into the owning * session's local buffers. */ if (RELATION_IS_OTHER_TEMP(rel)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); buffer = ReadBuffer(rel, 0); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); metad = BTPageGetMeta(page); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); j = 0; values[j++] = psprintf("%d", metad->btm_magic); values[j++] = psprintf("%d", metad->btm_version); values[j++] = psprintf("%d", metad->btm_root); values[j++] = psprintf("%d", metad->btm_level); values[j++] = psprintf("%d", metad->btm_fastroot); values[j++] = psprintf("%d", metad->btm_fastlevel); tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc), values); result = HeapTupleGetDatum(tuple); UnlockReleaseBuffer(buffer); relation_close(rel, AccessShareLock); PG_RETURN_DATUM(result); }
/* ----------------------------------------------- * bt_page_stats() * * Usage: SELECT * FROM bt_page_stats('t1_pkey', 1); * ----------------------------------------------- */ Datum bt_page_stats(PG_FUNCTION_ARGS) { text *relname = PG_GETARG_TEXT_PP(0); uint32 blkno = PG_GETARG_UINT32(1); Buffer buffer; Relation rel; RangeVar *relrv; Datum result; HeapTuple tuple; TupleDesc tupleDesc; int j; char *values[11]; BTPageStat stat; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use pageinspect functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", RelationGetRelationName(rel)); /* * Reject attempts to read non-local temporary relations; we would be * likely to get wrong data since we have no visibility into the owning * session's local buffers. */ if (RELATION_IS_OTHER_TEMP(rel)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); if (blkno == 0) elog(ERROR, "block 0 is a meta page"); CHECK_RELATION_BLOCK_RANGE(rel, blkno); buffer = ReadBuffer(rel, blkno); LockBuffer(buffer, BUFFER_LOCK_SHARE); /* keep compiler quiet */ stat.btpo_prev = stat.btpo_next = InvalidBlockNumber; stat.btpo_flags = stat.free_size = stat.avg_item_size = 0; GetBTPageStatistics(blkno, buffer, &stat); UnlockReleaseBuffer(buffer); relation_close(rel, AccessShareLock); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); j = 0; values[j++] = psprintf("%d", stat.blkno); values[j++] = psprintf("%c", stat.type); values[j++] = psprintf("%d", stat.live_items); values[j++] = psprintf("%d", stat.dead_items); values[j++] = psprintf("%d", stat.avg_item_size); values[j++] = psprintf("%d", stat.page_size); values[j++] = psprintf("%d", stat.free_size); values[j++] = psprintf("%d", stat.btpo_prev); values[j++] = psprintf("%d", stat.btpo_next); values[j++] = psprintf("%d", (stat.type == 'd') ? stat.btpo.xact : stat.btpo.level); values[j++] = psprintf("%d", stat.btpo_flags); tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc), values); result = HeapTupleGetDatum(tuple); PG_RETURN_DATUM(result); }
/* * build_function_result_tupdesc_d * * Build a RECORD function's tupledesc from the pg_proc proallargtypes, * proargmodes, and proargnames arrays. This is split out for the * convenience of ProcedureCreate, which needs to be able to compute the * tupledesc before actually creating the function. * * Returns NULL if there are not at least two OUT or INOUT arguments. */ TupleDesc build_function_result_tupdesc_d(Datum proallargtypes, Datum proargmodes, Datum proargnames) { TupleDesc desc; ArrayType *arr; int numargs; Oid *argtypes; char *argmodes; Datum *argnames = NULL; Oid *outargtypes; char **outargnames; int numoutargs; int nargnames; int i; /* Can't have output args if columns are null */ if (proallargtypes == PointerGetDatum(NULL) || proargmodes == PointerGetDatum(NULL)) return NULL; /* * We expect the arrays to be 1-D arrays of the right types; verify that. * For the OID and char arrays, we don't need to use deconstruct_array() * since the array data is just going to look like a C array of values. */ arr = DatumGetArrayTypeP(proallargtypes); /* ensure not toasted */ numargs = ARR_DIMS(arr)[0]; if (ARR_NDIM(arr) != 1 || numargs < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) elog(ERROR, "proallargtypes is not a 1-D Oid array"); argtypes = (Oid *) ARR_DATA_PTR(arr); arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */ if (ARR_NDIM(arr) != 1 || ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID) elog(ERROR, "proargmodes is not a 1-D char array"); argmodes = (char *) ARR_DATA_PTR(arr); if (proargnames != PointerGetDatum(NULL)) { arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */ if (ARR_NDIM(arr) != 1 || ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != TEXTOID) elog(ERROR, "proargnames is not a 1-D text array"); deconstruct_array(arr, TEXTOID, -1, false, 'i', &argnames, NULL, &nargnames); Assert(nargnames == numargs); } /* zero elements probably shouldn't happen, but handle it gracefully */ if (numargs <= 0) return NULL; /* extract output-argument types and names */ outargtypes = (Oid *) palloc(numargs * sizeof(Oid)); outargnames = (char **) palloc(numargs * sizeof(char *)); numoutargs = 0; for (i = 0; i < numargs; i++) { char *pname; if (argmodes[i] == PROARGMODE_IN || argmodes[i] == PROARGMODE_VARIADIC) continue; Assert(argmodes[i] == PROARGMODE_OUT || argmodes[i] == PROARGMODE_INOUT || argmodes[i] == PROARGMODE_TABLE); outargtypes[numoutargs] = argtypes[i]; if (argnames) pname = TextDatumGetCString(argnames[i]); else pname = NULL; if (pname == NULL || pname[0] == '\0') { /* Parameter is not named, so gin up a column name */ pname = psprintf("column%d", numoutargs + 1); } outargnames[numoutargs] = pname; numoutargs++; } /* * If there is no output argument, or only one, the function does not * return tuples. */ if (numoutargs < 2) return NULL; desc = CreateTemplateTupleDesc(numoutargs, false); for (i = 0; i < numoutargs; i++) { TupleDescInitEntry(desc, i + 1, outargnames[i], outargtypes[i], -1, 0); } return desc; }
VOID SetResolution( PDEVDATA pdev, DWORD res, WORD restype) /*++ Routine Description: Generate commands to set printer resolution. Arguments: pdev pointer to device data res desired resolution bPJL TRUE this is called at the beginning of a job FALSE if this called during the setup section Return Value: NONE --*/ { HPPD hppd = pdev->hppd; PRESOPTION pResOption; // We only need to do something when the requested // resolution type matches what the printer can do if (restype != hppd->wResType) return; // Check if the desired resolution is supported pResOption = PpdFindResolution(hppd, res); // Ignore if the desired resolution is not found if (pResOption == NULL) { DBGMSG1(DBG_LEVEL_TERSE, "No invocation string for resolution option: %d.\n", res); return; } switch (restype) { case RESTYPE_NORMAL: // Use normal PS code if (pResOption->pInvocation == NULL) { DBGMSG(DBG_LEVEL_ERROR, "Failed to set resolution."); } else { DscBeginFeature(pdev, "Resolution "); psprintf(pdev, "%d\n", res); psputs(pdev, pResOption->pInvocation); DscEndFeature(pdev); } break; case RESTYPE_JCL: // Use JCL code if (! PpdSupportsProtocol(hppd,PROTOCOL_PJL) || pResOption->pJclCode == NULL) { DBGMSG(DBG_LEVEL_ERROR, "Cannot set resolution using PJL commands.\n"); } else { psputs(pdev, pResOption->pJclCode); } break; case RESTYPE_EXITSERVER: // Use exitserver code if (pResOption->pSetResCode == NULL) { DBGMSG(DBG_LEVEL_ERROR, "Failed to set resolution."); } else { PSTR password = hppd->pPassword ? hppd->pPassword : "******"; psputs(pdev, "%%BeginExitServer: "); psputs(pdev, password); psprintf(pdev, "\n%%%%Resolution: %d\n", res); psputs(pdev, password); psputs(pdev, "\n"); psputs(pdev, pResOption->pSetResCode); psputs(pdev, "\n%%EndExitServer\n"); } break; } }
/* * create_tablespace_directories * * Attempt to create filesystem infrastructure linking $PGDATA/pg_tblspc/ * to the specified directory */ static void create_tablespace_directories(const char *location, const Oid tablespaceoid) { char *linkloc; char *location_with_version_dir; linkloc = psprintf("pg_tblspc/%u", tablespaceoid); location_with_version_dir = psprintf("%s/%s", location, TABLESPACE_VERSION_DIRECTORY); /* * Attempt to coerce target directory to safe permissions. If this fails, * it doesn't exist or has the wrong owner. */ if (chmod(location, S_IRWXU) != 0) { if (errno == ENOENT) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FILE), errmsg("directory \"%s\" does not exist", location), InRecovery ? errhint("Create this directory for the tablespace before " "restarting the server.") : 0)); else ereport(ERROR, (errcode_for_file_access(), errmsg("could not set permissions on directory \"%s\": %m", location))); } if (InRecovery) { struct stat st; /* * Our theory for replaying a CREATE is to forcibly drop the target * subdirectory if present, and then recreate it. This may be more * work than needed, but it is simple to implement. */ if (stat(location_with_version_dir, &st) == 0 && S_ISDIR(st.st_mode)) { if (!rmtree(location_with_version_dir, true)) /* If this failed, mkdir() below is going to error. */ ereport(WARNING, (errmsg("some useless files may be left behind in old database directory \"%s\"", location_with_version_dir))); } } /* * The creation of the version directory prevents more than one tablespace * in a single location. */ if (mkdir(location_with_version_dir, S_IRWXU) < 0) { if (errno == EEXIST) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), errmsg("directory \"%s\" already in use as a tablespace", location_with_version_dir))); else ereport(ERROR, (errcode_for_file_access(), errmsg("could not create directory \"%s\": %m", location_with_version_dir))); } /* Remove old symlink in recovery, in case it points to the wrong place */ if (InRecovery) { if (unlink(linkloc) < 0 && errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), errmsg("could not remove symbolic link \"%s\": %m", linkloc))); } /* * Create the symlink under PGDATA */ if (symlink(location, linkloc) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create symbolic link \"%s\": %m", linkloc))); pfree(linkloc); pfree(location_with_version_dir); }
Datum pgstrom_opencl_device_info(PG_FUNCTION_ARGS) { FuncCallContext *fncxt; Datum values[4]; bool isnull[4]; HeapTuple tuple; uint32 dindex; uint32 pindex; const pgstrom_device_info *dinfo; const char *key; const char *value; char buf[256]; int ofs = 0; if (SRF_IS_FIRSTCALL()) { TupleDesc tupdesc; MemoryContext oldcxt; fncxt = SRF_FIRSTCALL_INIT(); oldcxt = MemoryContextSwitchTo(fncxt->multi_call_memory_ctx); tupdesc = CreateTemplateTupleDesc(4, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "dnum", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "pnum", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "property", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "value", TEXTOID, -1, 0); fncxt->tuple_desc = BlessTupleDesc(tupdesc); fncxt->user_fctx = 0; MemoryContextSwitchTo(oldcxt); } fncxt = SRF_PERCALL_SETUP(); dindex = fncxt->call_cntr / 55; pindex = fncxt->call_cntr % 55; if (dindex == pgstrom_get_device_nums()) SRF_RETURN_DONE(fncxt); dinfo = pgstrom_get_device_info(dindex); Assert(dinfo != NULL); switch (pindex) { case 0: key = "platform index"; value = psprintf("%u", dinfo->pl_info->pl_index); break; case 1: key = "platform profile"; value = dinfo->pl_info->pl_profile; break; case 2: key = "platform version"; value = dinfo->pl_info->pl_version; break; case 3: key = "platform name"; value = dinfo->pl_info->pl_name; break; case 4: key = "platform vendor"; value = dinfo->pl_info->pl_vendor; break; case 5: key = "platform extensions"; value = dinfo->pl_info->pl_extensions; break; case 6: key = "address bits"; value = psprintf("%u", dinfo->dev_address_bits); break; case 7: key = "device available"; value = dinfo->dev_available ? "yes" : "no"; break; case 8: key = "compiler available"; value = dinfo->dev_compiler_available ? "yes" : "no"; break; case 9: key = "double fp config"; value = fp_config_to_cstring(dinfo->dev_double_fp_config); break; case 10: key = "little endian"; value = dinfo->dev_endian_little ? "yes" : "no"; break; case 11: key = "error correction support"; value = dinfo->dev_error_correction_support ? "yes" : "no"; break; case 12: key = "execution capabilities"; if (dinfo->dev_execution_capabilities & CL_EXEC_KERNEL) ofs += sprintf(buf + ofs, "OpenCL"); if (dinfo->dev_execution_capabilities & CL_EXEC_NATIVE_KERNEL) ofs += sprintf(buf + ofs, "%sNative", ofs > 0 ? ", " : ""); value = buf; break; case 13: key = "device extensions"; value = dinfo->dev_device_extensions; break; case 14: key = "global mem cache size"; value = psprintf("%lu", dinfo->dev_global_mem_cache_size); break; case 15: key = "global mem cache type"; switch (dinfo->dev_global_mem_cache_type) { case CL_NONE: value = "none"; break; case CL_READ_ONLY_CACHE: value = "read only"; break; case CL_READ_WRITE_CACHE: value = "read write"; break; default: value = "???"; break; } break; case 16: key = "global mem cacheline size"; value = psprintf("%u", dinfo->dev_global_mem_cacheline_size); break; case 17: key = "global mem size"; value = psprintf("%lu", dinfo->dev_global_mem_size); break; case 18: key = "host unified memory"; value = dinfo->dev_host_unified_memory ? "yes" : "no"; break; case 19: key = "local mem size"; value = psprintf("%lu", dinfo->dev_local_mem_size); break; case 20: key = "local mem type"; switch (dinfo->dev_local_mem_type) { case CL_LOCAL: value = "local"; break; case CL_GLOBAL: value = "global"; break; case CL_NONE: value = "none"; break; default: value = "???"; break; } break; case 21: key = "max clock frequency"; value = psprintf("%u", dinfo->dev_max_clock_frequency); break; case 22: key = "max compute units"; value = psprintf("%u", dinfo->dev_max_compute_units); break; case 23: key = "max constant args"; value = psprintf("%u", dinfo->dev_max_constant_args); break; case 24: key = "max constant buffer size"; value = psprintf("%lu", dinfo->dev_max_constant_buffer_size); break; case 25: key = "max mem alloc size"; value = psprintf("%lu", dinfo->dev_max_mem_alloc_size); break; case 26: key = "max parameter size"; value = psprintf("%lu", dinfo->dev_max_parameter_size); break; case 27: key = "max samplers"; value = psprintf("%u", dinfo->dev_max_samplers); break; case 28: key = "max work group size"; value = psprintf("%zu", dinfo->dev_max_work_group_size); break; case 29: key = "max work group dimensions"; value = psprintf("%u", dinfo->dev_max_work_item_dimensions); break; case 30: key = "max work item sizes"; value = psprintf("{%zu, %zu, %zu}", dinfo->dev_max_work_item_sizes[0], dinfo->dev_max_work_item_sizes[1], dinfo->dev_max_work_item_sizes[2]); break; case 31: key = "mem base address align"; value = psprintf("%u", dinfo->dev_mem_base_addr_align); break; case 32: key = "device name"; value = dinfo->dev_name; break; case 33: key = "native vector width (char)"; value = psprintf("%u", dinfo->dev_native_vector_width_char); break; case 34: key = "native vector width (short)"; value = psprintf("%u", dinfo->dev_native_vector_width_short); break; case 35: key = "native vector width (int)"; value = psprintf("%u", dinfo->dev_native_vector_width_int); break; case 36: key = "native vector width (long)"; value = psprintf("%u", dinfo->dev_native_vector_width_long); break; case 37: key = "native vector width (float)"; value = psprintf("%u", dinfo->dev_native_vector_width_float); break; case 38: key = "native vector width (double)"; value = psprintf("%u", dinfo->dev_native_vector_width_double); break; case 39: key = "opencl c version"; value = dinfo->dev_opencl_c_version; break; case 40: key = "preferred vector width (char)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_char); break; case 41: key = "preferred vector width (short)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_short); break; case 42: key = "preferred vector width (int)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_int); break; case 43: key = "preferred vector width (long)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_long); break; case 44: key = "preferred vector width (float)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_float); break; case 45: key = "preferred vector width (double)"; value = psprintf("%u", dinfo->dev_preferred_vector_width_double); break; case 46: key = "device profile"; value = dinfo->dev_profile; break; case 47: key = "profiling timer resolution"; value = psprintf("%zu", dinfo->dev_profiling_timer_resolution); break; case 48: key = "command queue properties"; if (dinfo->dev_queue_properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) ofs += sprintf(buf, "%sout of order", ofs > 0 ? ", " : ""); if (dinfo->dev_queue_properties & CL_QUEUE_PROFILING_ENABLE) ofs += sprintf(buf, "%sprofiling", ofs > 0 ? ", " : ""); value = buf; break; case 49: key = "single fp config"; value = fp_config_to_cstring(dinfo->dev_single_fp_config); break; case 50: key = "device type"; if (dinfo->dev_type & CL_DEVICE_TYPE_CPU) ofs += sprintf(buf, "%scpu", ofs > 0 ? ", " : ""); if (dinfo->dev_type & CL_DEVICE_TYPE_GPU) ofs += sprintf(buf, "%sgpu", ofs > 0 ? ", " : ""); if (dinfo->dev_type & CL_DEVICE_TYPE_ACCELERATOR) ofs += sprintf(buf, "%saccelerator", ofs > 0 ? ", " : ""); if (dinfo->dev_type & CL_DEVICE_TYPE_DEFAULT) ofs += sprintf(buf, "%sdefault", ofs > 0 ? ", " : ""); if (dinfo->dev_type & CL_DEVICE_TYPE_CUSTOM) ofs += sprintf(buf, "%scustom", ofs > 0 ? ", " : ""); value = buf; break; case 51: key = "device vendor"; value = dinfo->dev_vendor; break; case 52: key = "device vendor id"; value = psprintf("%u", dinfo->dev_vendor_id); break; case 53: key = "device version"; value = dinfo->dev_version; break; case 54: key = "driver version"; value = dinfo->driver_version; break; default: elog(ERROR, "unexpected property index"); break; } memset(isnull, 0, sizeof(isnull)); values[0] = Int32GetDatum(dindex); values[1] = Int32GetDatum(pindex); values[2] = CStringGetTextDatum(key); values[3] = CStringGetTextDatum(value); tuple = heap_form_tuple(fncxt->tuple_desc, values, isnull); SRF_RETURN_NEXT(fncxt, HeapTupleGetDatum(tuple)); }
/* * destroy_tablespace_directories * * Attempt to remove filesystem infrastructure for the tablespace. * * 'redo' indicates we are redoing a drop from XLOG; in that case we should * not throw an ERROR for problems, just LOG them. The worst consequence of * not removing files here would be failure to release some disk space, which * does not justify throwing an error that would require manual intervention * to get the database running again. * * Returns TRUE if successful, FALSE if some subdirectory is not empty */ static bool destroy_tablespace_directories(Oid tablespaceoid, bool redo) { char *linkloc; char *linkloc_with_version_dir; DIR *dirdesc; struct dirent *de; char *subfile; struct stat st; linkloc_with_version_dir = psprintf("pg_tblspc/%u/%s", tablespaceoid, TABLESPACE_VERSION_DIRECTORY); /* * Check if the tablespace still contains any files. We try to rmdir each * per-database directory we find in it. rmdir failure implies there are * still files in that subdirectory, so give up. (We do not have to worry * about undoing any already completed rmdirs, since the next attempt to * use the tablespace from that database will simply recreate the * subdirectory via TablespaceCreateDbspace.) * * Since we hold TablespaceCreateLock, no one else should be creating any * fresh subdirectories in parallel. It is possible that new files are * being created within subdirectories, though, so the rmdir call could * fail. Worst consequence is a less friendly error message. * * If redo is true then ENOENT is a likely outcome here, and we allow it * to pass without comment. In normal operation we still allow it, but * with a warning. This is because even though ProcessUtility disallows * DROP TABLESPACE in a transaction block, it's possible that a previous * DROP failed and rolled back after removing the tablespace directories * and/or symlink. We want to allow a new DROP attempt to succeed at * removing the catalog entries (and symlink if still present), so we * should not give a hard error here. */ dirdesc = AllocateDir(linkloc_with_version_dir); if (dirdesc == NULL) { if (errno == ENOENT) { if (!redo) ereport(WARNING, (errcode_for_file_access(), errmsg("could not open directory \"%s\": %m", linkloc_with_version_dir))); /* The symlink might still exist, so go try to remove it */ goto remove_symlink; } else if (redo) { /* in redo, just log other types of error */ ereport(LOG, (errcode_for_file_access(), errmsg("could not open directory \"%s\": %m", linkloc_with_version_dir))); pfree(linkloc_with_version_dir); return false; } /* else let ReadDir report the error */ } while ((de = ReadDir(dirdesc, linkloc_with_version_dir)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; subfile = psprintf("%s/%s", linkloc_with_version_dir, de->d_name); /* This check is just to deliver a friendlier error message */ if (!redo && !directory_is_empty(subfile)) { FreeDir(dirdesc); pfree(subfile); pfree(linkloc_with_version_dir); return false; } /* remove empty directory */ if (rmdir(subfile) < 0) ereport(redo ? LOG : ERROR, (errcode_for_file_access(), errmsg("could not remove directory \"%s\": %m", subfile))); pfree(subfile); } FreeDir(dirdesc); /* remove version directory */ if (rmdir(linkloc_with_version_dir) < 0) { ereport(redo ? LOG : ERROR, (errcode_for_file_access(), errmsg("could not remove directory \"%s\": %m", linkloc_with_version_dir))); pfree(linkloc_with_version_dir); return false; } /* * Try to remove the symlink. We must however deal with the possibility * that it's a directory instead of a symlink --- this could happen during * WAL replay (see TablespaceCreateDbspace), and it is also the case on * Windows where junction points lstat() as directories. * * Note: in the redo case, we'll return true if this final step fails; * there's no point in retrying it. Also, ENOENT should provoke no more * than a warning. */ remove_symlink: linkloc = pstrdup(linkloc_with_version_dir); get_parent_directory(linkloc); if (lstat(linkloc, &st) == 0 && S_ISDIR(st.st_mode)) { if (rmdir(linkloc) < 0) ereport(redo ? LOG : ERROR, (errcode_for_file_access(), errmsg("could not remove directory \"%s\": %m", linkloc))); } else { if (unlink(linkloc) < 0) ereport(redo ? LOG : (errno == ENOENT ? WARNING : ERROR), (errcode_for_file_access(), errmsg("could not remove symbolic link \"%s\": %m", linkloc))); } pfree(linkloc_with_version_dir); pfree(linkloc); return true; }
/* * parseCommandLine() * * Parses the command line (argc, argv[]) and loads structures */ void parseCommandLine(int argc, char *argv[]) { static struct option long_options[] = { {"old-datadir", required_argument, NULL, 'd'}, {"new-datadir", required_argument, NULL, 'D'}, {"old-bindir", required_argument, NULL, 'b'}, {"new-bindir", required_argument, NULL, 'B'}, {"old-options", required_argument, NULL, 'o'}, {"new-options", required_argument, NULL, 'O'}, {"old-port", required_argument, NULL, 'p'}, {"new-port", required_argument, NULL, 'P'}, {"username", required_argument, NULL, 'U'}, {"check", no_argument, NULL, 'c'}, {"link", no_argument, NULL, 'k'}, {"retain", no_argument, NULL, 'r'}, {"jobs", required_argument, NULL, 'j'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; int option; /* Command line option */ int optindex = 0; /* used by getopt_long */ int os_user_effective_id; FILE *fp; char **filename; time_t run_time = time(NULL); user_opts.transfer_mode = TRANSFER_MODE_COPY; os_info.progname = get_progname(argv[0]); /* Process libpq env. variables; load values here for usage() output */ old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT; new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT; os_user_effective_id = get_user_info(&os_info.user); /* we override just the database user name; we got the OS id above */ if (getenv("PGUSER")) { pg_free(os_info.user); /* must save value, getenv()'s pointer is not stable */ os_info.user = pg_strdup(getenv("PGUSER")); } if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_upgrade (PostgreSQL) " PG_VERSION); exit(0); } } /* Allow help and version to be run as root, so do the test here. */ if (os_user_effective_id == 0) pg_fatal("%s: cannot be run as root\n", os_info.progname); if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL) pg_fatal("cannot write to log file %s\n", INTERNAL_LOG_FILE); while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v", long_options, &optindex)) != -1) { switch (option) { case 'b': old_cluster.bindir = pg_strdup(optarg); break; case 'B': new_cluster.bindir = pg_strdup(optarg); break; case 'c': user_opts.check = true; break; case 'd': old_cluster.pgdata = pg_strdup(optarg); old_cluster.pgconfig = pg_strdup(optarg); break; case 'D': new_cluster.pgdata = pg_strdup(optarg); new_cluster.pgconfig = pg_strdup(optarg); break; case 'j': user_opts.jobs = atoi(optarg); break; case 'k': user_opts.transfer_mode = TRANSFER_MODE_LINK; break; case 'o': old_cluster.pgopts = pg_strdup(optarg); break; case 'O': new_cluster.pgopts = pg_strdup(optarg); break; /* * Someday, the port number option could be removed and passed * using -o/-O, but that requires postmaster -C to be * supported on all old/new versions. */ case 'p': if ((old_cluster.port = atoi(optarg)) <= 0) { pg_fatal("invalid old port number\n"); exit(1); } break; case 'P': if ((new_cluster.port = atoi(optarg)) <= 0) { pg_fatal("invalid new port number\n"); exit(1); } break; case 'r': log_opts.retain = true; break; case 'U': pg_free(os_info.user); os_info.user = pg_strdup(optarg); os_info.user_specified = true; /* * Push the user name into the environment so pre-9.1 * pg_ctl/libpq uses it. */ pg_putenv("PGUSER", os_info.user); break; case 'v': pg_log(PG_REPORT, "Running in verbose mode\n"); log_opts.verbose = true; break; default: pg_fatal("Try \"%s --help\" for more information.\n", os_info.progname); break; } } /* label start of upgrade in logfiles */ for (filename = output_files; *filename != NULL; filename++) { if ((fp = fopen_priv(*filename, "a")) == NULL) pg_fatal("cannot write to log file %s\n", *filename); /* Start with newline because we might be appending to a file. */ fprintf(fp, "\n" "-----------------------------------------------------------------\n" " pg_upgrade run on %s" "-----------------------------------------------------------------\n\n", ctime(&run_time)); fclose(fp); } /* Turn off read-only mode; add prefix to PGOPTIONS? */ if (getenv("PGOPTIONS")) { char *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY, getenv("PGOPTIONS")); pg_putenv("PGOPTIONS", pgoptions); pfree(pgoptions); } else pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY); /* Get values from env if not already set */ check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b", "old cluster binaries reside"); check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B", "new cluster binaries reside"); check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig, "PGDATAOLD", "-d", "old cluster data resides"); check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig, "PGDATANEW", "-D", "new cluster data resides"); #ifdef WIN32 /* * On Windows, initdb --sync-only will fail with a "Permission denied" * error on file pg_upgrade_utility.log if pg_upgrade is run inside * the new cluster directory, so we do a check here. */ { char cwd[MAXPGPATH], new_cluster_pgdata[MAXPGPATH]; strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH); canonicalize_path(new_cluster_pgdata); if (!getcwd(cwd, MAXPGPATH)) pg_fatal("cannot find current directory\n"); canonicalize_path(cwd); if (path_is_prefix_of_path(new_cluster_pgdata, cwd)) pg_fatal("cannot run pg_upgrade from inside the new cluster data directory on Windows\n"); } #endif }
VOID PsSelectPrinterFeatures( PDEVDATA pdev, WORD section ) /*++ Routine Description: Select printer specific feature to appear in a given section. Arguments: pdev - Pointer to our DEVDATA structure section - DSC section we're currently in Return Value: NONE --*/ { WORD index; PFEATUREDATA pFeatureData; PUIGROUP pUiGroup; PUIOPTION pUiOption; // // Prepare data for handling printer specific feature if it's not done already. // if (!pdev->pFeatureData && !PrepareFeatureData(pdev)) { DBGERRMSG("PrepareFeatureData"); return; } // // For each requested feature, check if it should be sent to // the printer in the current DSC section. // for (index = 0, pFeatureData = pdev->pFeatureData; index < pdev->cSelectedFeature; index ++, pFeatureData++) { // // Find the UIOPTION object corresponding to the requested feature/selection. // // HACK: PageSize feature is handled differently here because it involves // lots of legacy stuff which we don't want to touch at this point. // if (! (pFeatureData->section & section)) continue; if (pdev->hppd->pPageSizes && pdev->hppd->pPageSizes->featureIndex == pFeatureData->feature) { PsSelectFormAndTray(pdev); } else if (PpdFindFeatureSelection( pdev->hppd, pFeatureData->feature, pFeatureData->option, &pUiGroup, &pUiOption)) { DBGMSG1(DBG_LEVEL_VERBOSE, "Feature: %s\n", pUiGroup->pName); DBGMSG1(DBG_LEVEL_VERBOSE, "Selection: %s\n", pUiOption->pName); // // If we're not in JCLSetup section, then enclose the feature // invocation in a mark/cleartomark pair. // if (section != ODS_JCLSETUP) { DscBeginFeature(pdev, pUiGroup->pName); psprintf(pdev, " %s\n", pUiOption->pName); } if (pUiOption->pInvocation) psputs(pdev, pUiOption->pInvocation); if (section != ODS_JCLSETUP) DscEndFeature(pdev); } } }
/* * * main * */ int main(int argc, char *argv[]) { struct adhoc_opts options; int successResult; char *password = NULL; char *password_prompt = NULL; bool new_pass; set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql")); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(); exit(EXIT_SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { showVersion(); exit(EXIT_SUCCESS); } } #ifdef WIN32 setvbuf(stderr, NULL, _IONBF, 0); #endif pset.progname = get_progname(argv[0]); pset.db = NULL; setDecimalLocale(); pset.encoding = PQenv2encoding(); pset.queryFout = stdout; pset.queryFoutPipe = false; pset.cur_cmd_source = stdin; pset.cur_cmd_interactive = false; /* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */ pset.popt.topt.format = PRINT_ALIGNED; pset.popt.topt.border = 1; pset.popt.topt.pager = 1; pset.popt.topt.start_table = true; pset.popt.topt.stop_table = true; pset.popt.topt.default_footer = true; /* We must get COLUMNS here before readline() sets it */ pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0; pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout))); pset.getPassword = TRI_DEFAULT; EstablishVariableSpace(); SetVariable(pset.vars, "VERSION", PG_VERSION_STR); /* Default values for variables */ SetVariableBool(pset.vars, "AUTOCOMMIT"); SetVariable(pset.vars, "VERBOSITY", "default"); SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1); SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2); SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3); parse_psql_options(argc, argv, &options); /* * If no action was specified and we're in non-interactive mode, treat it * as if the user had specified "-f -". This lets single-transaction mode * work in this case. */ if (options.action == ACT_NOTHING && pset.notty) { options.action = ACT_FILE; options.action_string = NULL; } /* Bail out if -1 was specified but will be ignored. */ if (options.single_txn && options.action != ACT_FILE && options.action == ACT_NOTHING) { fprintf(stderr, _("%s: -1 can only be used in non-interactive mode\n"), pset.progname); exit(EXIT_FAILURE); } if (!pset.popt.topt.fieldSep.separator && !pset.popt.topt.fieldSep.separator_zero) { pset.popt.topt.fieldSep.separator = pg_strdup(DEFAULT_FIELD_SEP); pset.popt.topt.fieldSep.separator_zero = false; } if (!pset.popt.topt.recordSep.separator && !pset.popt.topt.recordSep.separator_zero) { pset.popt.topt.recordSep.separator = pg_strdup(DEFAULT_RECORD_SEP); pset.popt.topt.recordSep.separator_zero = false; } if (options.username == NULL) password_prompt = pg_strdup(_("Password: "******"Password for user %s: "), options.username); if (pset.getPassword == TRI_YES) password = simple_prompt(password_prompt, 100, false); /* loop until we have a password if requested by backend */ do { #define PARAMS_ARRAY_SIZE 8 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); keywords[0] = "host"; values[0] = options.host; keywords[1] = "port"; values[1] = options.port; keywords[2] = "user"; values[2] = options.username; keywords[3] = "password"; values[3] = password; keywords[4] = "dbname"; values[4] = (options.action == ACT_LIST_DB && options.dbname == NULL) ? "postgres" : options.dbname; keywords[5] = "fallback_application_name"; values[5] = pset.progname; keywords[6] = "client_encoding"; values[6] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto"; keywords[7] = NULL; values[7] = NULL; new_pass = false; pset.db = PQconnectdbParams(keywords, values, true); free(keywords); free(values); if (PQstatus(pset.db) == CONNECTION_BAD && PQconnectionNeedsPassword(pset.db) && password == NULL && pset.getPassword != TRI_NO) { PQfinish(pset.db); password = simple_prompt(password_prompt, 100, false); new_pass = true; } } while (new_pass); free(password); free(password_prompt); if (PQstatus(pset.db) == CONNECTION_BAD) { fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db)); PQfinish(pset.db); exit(EXIT_BADCONN); } setup_cancel_handler(); PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); SyncVariables(); if (options.action == ACT_LIST_DB) { int success; if (!options.no_psqlrc) process_psqlrc(argv[0]); success = listAllDbs(NULL, false); PQfinish(pset.db); exit(success ? EXIT_SUCCESS : EXIT_FAILURE); } if (options.logfilename) { pset.logfile = fopen(options.logfilename, "a"); if (!pset.logfile) fprintf(stderr, _("%s: could not open log file \"%s\": %s\n"), pset.progname, options.logfilename, strerror(errno)); } /* * Now find something to do */ /* * process file given by -f */ if (options.action == ACT_FILE) { if (!options.no_psqlrc) process_psqlrc(argv[0]); successResult = process_file(options.action_string, options.single_txn, false); } /* * process slash command if one was given to -c */ else if (options.action == ACT_SINGLE_SLASH) { PsqlScanState scan_state; if (pset.echo == PSQL_ECHO_ALL) puts(options.action_string); scan_state = psql_scan_create(); psql_scan_setup(scan_state, options.action_string, strlen(options.action_string)); successResult = HandleSlashCmds(scan_state, NULL) != PSQL_CMD_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; psql_scan_destroy(scan_state); } /* * If the query given to -c was a normal one, send it */ else if (options.action == ACT_SINGLE_QUERY) { if (pset.echo == PSQL_ECHO_ALL) puts(options.action_string); successResult = SendQuery(options.action_string) ? EXIT_SUCCESS : EXIT_FAILURE; } /* * or otherwise enter interactive main loop */ else { if (!options.no_psqlrc) process_psqlrc(argv[0]); connection_warnings(true); if (!pset.quiet) printf(_("Type \"help\" for help.\n\n")); initializeInput(options.no_readline ? 0 : 1); successResult = MainLoop(stdin); } /* clean up */ if (pset.logfile) fclose(pset.logfile); PQfinish(pset.db); setQFout(NULL); return successResult; }
BOOL bSendDeviceSetup( PDEVDATA pdev ) /*++ Routine Description: Send page setup code to the printer. This is called at the beginning of every page. Arguments: pdev - Pointer to our DEVDATA structure Return Value: TRUE if successful, FALSE if error --*/ { PSTR pstr; HPPD hppd = pdev->hppd; // // Clear the current page if Negative Output option is selected // if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NEG) { psputs(pdev, "gsave clippath 1 setgray fill grestore\n"); } // Rotate 90 degrees counterclockwise for normal landscape // or 90 degrees clockwise for rotated landscape if (pdev->dm.dmPublic.dmOrientation == DMORIENT_LANDSCAPE) { SetLandscape(pdev, (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_LSROTATE) != 0, pdev->CurForm.PaperSize.height, pdev->CurForm.PaperSize.width); } if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_MIRROR) { psprintf(pdev, "%f %f translate -1 1 scale\n", pdev->CurForm.ImageArea.right - pdev->CurForm.ImageArea.left, 0); } /* Translate origin to upper left corner a la GDI */ psprintf(pdev, "%f %f translate ", pdev->CurForm.ImageArea.left, pdev->CurForm.ImageArea.top); /* Flip y-axis to point downwards and scale from points to dpi */ psprintf(pdev, "%d %d div dup neg scale\n", 72, pdev->dm.dmPublic.dmPrintQuality); /* Snap to pixel */ psputs(pdev, "0 0 transform .25 add round .25 sub exch .25 add " "round .25 sub exch itransform translate\n"); return TRUE; }
/* * Actually do a base backup for the specified tablespaces. * * This is split out mainly to avoid complaints about "variable might be * clobbered by longjmp" from stupider versions of gcc. */ static void perform_base_backup(basebackup_options *opt, DIR *tblspcdir) { XLogRecPtr startptr; TimeLineID starttli; XLogRecPtr endptr; TimeLineID endtli; StringInfo labelfile; StringInfo tblspc_map_file = NULL; int datadirpathlen; List *tablespaces = NIL; datadirpathlen = strlen(DataDir); backup_started_in_recovery = RecoveryInProgress(); labelfile = makeStringInfo(); tblspc_map_file = makeStringInfo(); startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli, labelfile, tblspcdir, &tablespaces, tblspc_map_file, opt->progress, opt->sendtblspcmapfile); /* * Once do_pg_start_backup has been called, ensure that any failure causes * us to abort the backup so we don't "leak" a backup counter. For this * reason, *all* functionality between do_pg_start_backup() and * do_pg_stop_backup() should be inside the error cleanup block! */ PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); { ListCell *lc; tablespaceinfo *ti; SendXlogRecPtrResult(startptr, starttli); /* * Calculate the relative path of temporary statistics directory in * order to skip the files which are located in that directory later. */ if (is_absolute_path(pgstat_stat_directory) && strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0) statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1); else if (strncmp(pgstat_stat_directory, "./", 2) != 0) statrelpath = psprintf("./%s", pgstat_stat_directory); else statrelpath = pgstat_stat_directory; /* Add a node for the base directory at the end */ ti = palloc0(sizeof(tablespaceinfo)); ti->size = opt->progress ? sendDir(".", 1, true, tablespaces, true) : -1; tablespaces = lappend(tablespaces, ti); /* Send tablespace header */ SendBackupHeader(tablespaces); /* Setup and activate network throttling, if client requested it */ if (opt->maxrate > 0) { throttling_sample = (int64) opt->maxrate * (int64) 1024 / THROTTLING_FREQUENCY; /* * The minimum amount of time for throttling_sample bytes to be * transferred. */ elapsed_min_unit = USECS_PER_SEC / THROTTLING_FREQUENCY; /* Enable throttling. */ throttling_counter = 0; /* The 'real data' starts now (header was ignored). */ throttled_last = GetCurrentIntegerTimestamp(); } else { /* Disable throttling. */ throttling_counter = -1; } /* Send off our tablespaces one by one */ foreach(lc, tablespaces) { tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc); StringInfoData buf; /* Send CopyOutResponse message */ pq_beginmessage(&buf, 'H'); pq_sendbyte(&buf, 0); /* overall format */ pq_sendint(&buf, 0, 2); /* natts */ pq_endmessage(&buf); if (ti->path == NULL) { struct stat statbuf; /* In the main tar, include the backup_label first... */ sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data); /* * Send tablespace_map file if required and then the bulk of * the files. */ if (tblspc_map_file && opt->sendtblspcmapfile) { sendFileWithContent(TABLESPACE_MAP, tblspc_map_file->data); sendDir(".", 1, false, tablespaces, false); } else sendDir(".", 1, false, tablespaces, true); /* ... and pg_control after everything else. */ if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat control file \"%s\": %m", XLOG_CONTROL_FILE))); sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false); } else sendTablespace(ti->path, false); /* * If we're including WAL, and this is the main data directory we * don't terminate the tar stream here. Instead, we will append * the xlog files below and terminate it then. This is safe since * the main data directory is always sent *last*. */ if (opt->includewal && ti->path == NULL) { Assert(lnext(lc) == NULL); } else pq_putemptymessage('c'); /* CopyDone */ } }
VOID PsSelectFormAndTray( PDEVDATA pdev ) /*++ Routine Description: This function pick the tray for a particular form selected, depends on the user request in the UI Arguments: pdev - Pointer to our PDEVDATA Return Value: NONE --*/ { BOOL IsManual; PINPUTSLOT pInputSlot; HPPD hppd = pdev->hppd; PSTR pstr; // If a valid input slot is specified, then we'll instruct // the printer to draw paper from that slot. Otherwise, // we'll tell printer to select input slot based on paper size. IsManual = FALSE; pInputSlot = NULL; if ((pdev->dm.dmPublic.dmFields & DM_DEFAULTSOURCE) && (pdev->dm.dmPublic.dmDefaultSource != DMBIN_FORMSOURCE)) { DWORD SlotNum, cInputSlots; SlotNum = pdev->dm.dmPublic.dmDefaultSource; cInputSlots = UIGROUP_CountOptions(hppd->pInputSlots); if (SlotNum == DMBIN_MANUAL || SlotNum == DMBIN_ENVMANUAL) { // Manual feed is requested IsManual = TRUE; } else if (SlotNum >= DMBIN_USER && SlotNum < DMBIN_USER+cInputSlots) { // A valid input slot is requested pInputSlot = (PINPUTSLOT) LISTOBJ_FindIndexed( (PLISTOBJ) hppd->pInputSlots->pUiOptions, SlotNum - DMBIN_USER); } } else if (pdev->CurForm.FormName[0] != NUL) { // No input slot is specifically requested. Go through // the form to tray assignment table and find the input // slot matching the requested form. pInputSlot = MatchFormToTray(pdev, &IsManual); } if (IsManual) { // If manual feed feature is requested, then // generate PostScript code to enable it. PsSelectManualFeed(pdev, TRUE); } else { // Disable manual feed if it's currently enabled PsSelectManualFeed(pdev, FALSE); if (pInputSlot != NULL) { // If an input slot is designated, then generate // PostScript code to select it. DscBeginFeature(pdev, "InputSlot "); psprintf(pdev, "%s\n", pInputSlot->pName); if (pInputSlot->pInvocation != NULL) psputs(pdev, pInputSlot->pInvocation); DscEndFeature(pdev); } } if (IsCustomPrinterForm(& pdev->CurForm)) { // If the custom page size is requested, then generate // appropriate PostScript code to send to the printer. DscBeginFeature(pdev, "CustomPageSize\n"); PsSelectCustomPageSize(pdev); DscEndFeature(pdev); } else if (pInputSlot == NULL || pInputSlot->bReqPageRgn) { BOOL bRegion; PMEDIAOPTION pMediaOption; // If an input slot was selected and it doesn't require // PageRegion, then we are done. Otherwise, we need to // generate either PageRegion or PageSize code (depending // on whether a tray was selected). bRegion = IsManual || (pInputSlot != NULL); DscBeginFeature(pdev, bRegion ? "PageRegion" : "PageSize"); psprintf(pdev, " %s\n", pdev->CurForm.PaperName); // Find the invocation string to send to the printer pMediaOption = (PMEDIAOPTION) LISTOBJ_FindIndexed( (PLISTOBJ) hppd->pPageSizes->pUiOptions, pdev->CurForm.featureIndex); if (pMediaOption != NULL) { pstr = bRegion ? pMediaOption->pPageRgnCode : pMediaOption->pPageSizeCode; if (pstr != NULL) { psputs(pdev, pstr); } } DscEndFeature(pdev); } }
/* cash_out() * Function to convert cash to a dollars and cents representation, using * the lc_monetary locale's formatting. */ Datum cash_out(PG_FUNCTION_ARGS) { Cash value = PG_GETARG_CASH(0); char *result; char buf[128]; char *bufptr; int digit_pos; int points, mon_group; char dsymbol; const char *ssymbol, *csymbol, *signsymbol; char sign_posn, cs_precedes, sep_by_space; struct lconv *lconvert = PGLC_localeconv(); /* see comments about frac_digits in cash_in() */ points = lconvert->frac_digits; if (points < 0 || points > 10) points = 2; /* best guess in this case, I think */ /* * As with frac_digits, must apply a range check to mon_grouping to avoid * being fooled by variant CHAR_MAX values. */ mon_group = *lconvert->mon_grouping; if (mon_group <= 0 || mon_group > 6) mon_group = 3; /* we restrict dsymbol to be a single byte, but not the other symbols */ if (*lconvert->mon_decimal_point != '\0' && lconvert->mon_decimal_point[1] == '\0') dsymbol = *lconvert->mon_decimal_point; else dsymbol = '.'; if (*lconvert->mon_thousands_sep != '\0') ssymbol = lconvert->mon_thousands_sep; else /* ssymbol should not equal dsymbol */ ssymbol = (dsymbol != ',') ? "," : "."; csymbol = (*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$"; if (value < 0) { /* make the amount positive for digit-reconstruction loop */ value = -value; /* set up formatting data */ signsymbol = (*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-"; sign_posn = lconvert->n_sign_posn; cs_precedes = lconvert->n_cs_precedes; sep_by_space = lconvert->n_sep_by_space; } else { signsymbol = lconvert->positive_sign; sign_posn = lconvert->p_sign_posn; cs_precedes = lconvert->p_cs_precedes; sep_by_space = lconvert->p_sep_by_space; } /* we build the digits+decimal-point+sep string right-to-left in buf[] */ bufptr = buf + sizeof(buf) - 1; *bufptr = '\0'; /* * Generate digits till there are no non-zero digits left and we emitted * at least one to the left of the decimal point. digit_pos is the * current digit position, with zero as the digit just left of the decimal * point, increasing to the right. */ digit_pos = points; do { if (points && digit_pos == 0) { /* insert decimal point, but not if value cannot be fractional */ *(--bufptr) = dsymbol; } else if (digit_pos < 0 && (digit_pos % mon_group) == 0) { /* insert thousands sep, but only to left of radix point */ bufptr -= strlen(ssymbol); memcpy(bufptr, ssymbol, strlen(ssymbol)); } *(--bufptr) = ((uint64) value % 10) + '0'; value = ((uint64) value) / 10; digit_pos--; } while (value || digit_pos >= 0); /*---------- * Now, attach currency symbol and sign symbol in the correct order. * * The POSIX spec defines these values controlling this code: * * p/n_sign_posn: * 0 Parentheses enclose the quantity and the currency_symbol. * 1 The sign string precedes the quantity and the currency_symbol. * 2 The sign string succeeds the quantity and the currency_symbol. * 3 The sign string precedes the currency_symbol. * 4 The sign string succeeds the currency_symbol. * * p/n_cs_precedes: 0 means currency symbol after value, else before it. * * p/n_sep_by_space: * 0 No <space> separates the currency symbol and value. * 1 If the currency symbol and sign string are adjacent, a <space> * separates them from the value; otherwise, a <space> separates * the currency symbol from the value. * 2 If the currency symbol and sign string are adjacent, a <space> * separates them; otherwise, a <space> separates the sign string * from the value. *---------- */ switch (sign_posn) { case 0: if (cs_precedes) result = psprintf("(%s%s%s)", csymbol, (sep_by_space == 1) ? " " : "", bufptr); else result = psprintf("(%s%s%s)", bufptr, (sep_by_space == 1) ? " " : "", csymbol); break; case 1: default: if (cs_precedes) result = psprintf("%s%s%s%s%s", signsymbol, (sep_by_space == 2) ? " " : "", csymbol, (sep_by_space == 1) ? " " : "", bufptr); else result = psprintf("%s%s%s%s%s", signsymbol, (sep_by_space == 2) ? " " : "", bufptr, (sep_by_space == 1) ? " " : "", csymbol); break; case 2: if (cs_precedes) result = psprintf("%s%s%s%s%s", csymbol, (sep_by_space == 1) ? " " : "", bufptr, (sep_by_space == 2) ? " " : "", signsymbol); else result = psprintf("%s%s%s%s%s", bufptr, (sep_by_space == 1) ? " " : "", csymbol, (sep_by_space == 2) ? " " : "", signsymbol); break; case 3: if (cs_precedes) result = psprintf("%s%s%s%s%s", signsymbol, (sep_by_space == 2) ? " " : "", csymbol, (sep_by_space == 1) ? " " : "", bufptr); else result = psprintf("%s%s%s%s%s", bufptr, (sep_by_space == 1) ? " " : "", signsymbol, (sep_by_space == 2) ? " " : "", csymbol); break; case 4: if (cs_precedes) result = psprintf("%s%s%s%s%s", csymbol, (sep_by_space == 2) ? " " : "", signsymbol, (sep_by_space == 1) ? " " : "", bufptr); else result = psprintf("%s%s%s%s%s", bufptr, (sep_by_space == 1) ? " " : "", csymbol, (sep_by_space == 2) ? " " : "", signsymbol); break; } PG_RETURN_CSTRING(result); }
BOOL bOutputHeader( PDEVDATA pdev ) /*++ Routine Description: Send PostScript output header to the printer Arguments: pdev - Pointer to our DEVDATA Return Value: TRUE if successful, FALSE otherwise --*/ { CHAR *pstr; HPPD hppd = pdev->hppd; ENG_TIME_FIELDS localtime; // // Process information in the public devmode fields and map it to printer // feature selections. This must be called before PsSelectPrinterFeatures. // HandlePublicDevmodeOptions(pdev); // // Spit out job control stuff at the beginning of a job if necessary // if (! bPageIndependence(pdev) && ! (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NO_JOB_CONTROL)) { if (PpdSupportsProtocol(hppd, PROTOCOL_PJL)) { // Universal exit language if (hppd->pJclBegin != NULL) { psputs(pdev, hppd->pJclBegin); } else { DBGMSG(DBG_LEVEL_TERSE, "No JCLBegin code.\n"); psputs(pdev, "\033%-12345X"); } // If the printer uses PJL commands to set resolution, // then do it before the job. SetResolution(pdev, pdev->dm.dmPublic.dmPrintQuality, RESTYPE_JCL); // Select printer specific features - JCLSetup PsSelectPrinterFeatures(pdev, ODS_JCLSETUP); // if the printer supports job switching, put the printer into // postscript mode now. if (hppd->pJclToPs != NULL) { psputs(pdev, hppd->pJclToPs); } else { DBGMSG(DBG_LEVEL_TERSE, "No JCLToPSInterpreter code.\n"); psputs(pdev, "@PJL ENTER LANGUAGE=POSTSCRIPT\n"); } } else if (PpdSupportsProtocol(hppd, PROTOCOL_SIC)) { // directly call pswrite to output the necessary escape commands. // psputs will NOT output '\000'. pswrite(pdev, "\033\133\113\030\000\006\061\010\000\000\000\000\000", 13); pswrite(pdev, "\000\000\000\000\000\000\000\000\004\033\133\113\003", 13); pswrite(pdev, "\000\006\061\010\004", 5); } else if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_CTRLD_BEFORE) { // send a ^D before the job pswrite(pdev, "\004", 1); } } psputs(pdev, "%!PS-Adobe-3.0\n"); // output the title of the document. if (pdev->pwstrDocName) { CHAR buf[128]; CopyUnicode2Str(buf, pdev->pwstrDocName, 128); psprintf(pdev, "%%%%Title: %s\n", buf); } else psputs(pdev, "%%Title: Untitled Document\n"); // let the world know who we are. psputs(pdev, "%%Creator: Windows NT 4.0\n"); // print the date and time of creation. EngQueryLocalTime(&localtime); psprintf(pdev, "%%%%CreationDate: %d:%d %d/%d/%d\n", localtime.usHour, localtime.usMinute, localtime.usMonth, localtime.usDay, localtime.usYear); if (! (pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE)) psputs(pdev, "%%Pages: (atend)\n"); // mark the bounding box of the document. psputs(pdev, "%%BoundingBox: "); psprintf(pdev, "%d %d %d %d\n", PSREAL2INT(pdev->CurForm.ImageArea.left), PSREAL2INT(pdev->CurForm.ImageArea.bottom), PSREAL2INT(pdev->CurForm.ImageArea.right), PSREAL2INT(pdev->CurForm.ImageArea.top)); if (pdev->cCopies > 1) psprintf(pdev, "%%%%Requirements: numcopies(%d) collate\n", pdev->cCopies); DscLanguageLevel(pdev, pdev->hppd->dwLangLevel); DscOutputFontComments(pdev, FALSE); // we are done with the comments portion of the document. psputs(pdev, "%%EndComments\n"); // If the printer uses exitserver commands to set // resolution, then do it before any other PS code. SetResolution(pdev, pdev->dm.dmPublic.dmPrintQuality, RESTYPE_EXITSERVER); // define our procedure set. if (!(pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE)) { psputs(pdev, "%%BeginProlog\n"); DownloadNTProcSet(pdev, TRUE); psputs(pdev, "%%EndProlog\n"); } // do the device setup. psputs(pdev, "%%BeginSetup\n"); // set job and wait timeout values SetTimeoutValues(pdev); // Set number of copies psprintf(pdev, "/#copies %d def\n", pdev->cCopies); // Select printer specific features - DocumentSetup and AnySetup PsSelectPrinterFeatures(pdev, ODS_DOCSETUP|ODS_ANYSETUP); // The implemention of EPSPRINTING escape here just follows Win31 if ((pdev->dwFlags & PDEV_EPSPRINTING_ESCAPE) && (pdev->dm.dmPublic.dmOrientation == DMORIENT_LANDSCAPE)) { SetLandscape(pdev, TRUE, pdev->CurForm.PaperSize.height, pdev->CurForm.PaperSize.width); } // // Invert the default transfer function if Negative Output option is selected // if (pdev->dm.dmPrivate.dwFlags & PSDEVMODE_NEG) { psputs(pdev, "[currenttransfer /exec load {1 exch sub} /exec load] cvx settransfer\n"); } psputs(pdev, "%%EndSetup\n"); // the form-tray information has already been sent for the first page. pdev->dwFlags &= ~PDEV_RESETPDEV; return(TRUE); }
/* * Check given password for given user, and return STATUS_OK or STATUS_ERROR. * In the error case, optionally store a palloc'd string at *logdetail * that will be sent to the postmaster log (but not the client). */ int md5_crypt_verify(const Port *port, const char *role, char *client_pass, char **logdetail) { int retval = STATUS_ERROR; char *shadow_pass, *crypt_pwd; TimestampTz vuntil = 0; char *crypt_client_pass = client_pass; HeapTuple roleTup; Datum datum; bool isnull; /* Get role info from pg_authid */ roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(role)); if (!HeapTupleIsValid(roleTup)) { *logdetail = psprintf(_("Role \"%s\" does not exist."), role); return STATUS_ERROR; /* no such user */ } datum = SysCacheGetAttr(AUTHNAME, roleTup, Anum_pg_authid_rolpassword, &isnull); if (isnull) { ReleaseSysCache(roleTup); *logdetail = psprintf(_("User \"%s\" has no password assigned."), role); return STATUS_ERROR; /* user has no password */ } shadow_pass = TextDatumGetCString(datum); datum = SysCacheGetAttr(AUTHNAME, roleTup, Anum_pg_authid_rolvaliduntil, &isnull); if (!isnull) vuntil = DatumGetTimestampTz(datum); ReleaseSysCache(roleTup); if (*shadow_pass == '\0') { *logdetail = psprintf(_("User \"%s\" has an empty password."), role); return STATUS_ERROR; /* empty password */ } /* * Compare with the encrypted or plain password depending on the * authentication method being used for this connection. (We do not * bother setting logdetail for pg_md5_encrypt failure: the only possible * error is out-of-memory, which is unlikely, and if it did happen adding * a psprintf call would only make things worse.) */ switch (port->hba->auth_method) { case uaMD5: crypt_pwd = palloc(MD5_PASSWD_LEN + 1); if (isMD5(shadow_pass)) { /* stored password already encrypted, only do salt */ if (!pg_md5_encrypt(shadow_pass + strlen("md5"), port->md5Salt, sizeof(port->md5Salt), crypt_pwd)) { pfree(crypt_pwd); return STATUS_ERROR; } } else { /* stored password is plain, double-encrypt */ char *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1); if (!pg_md5_encrypt(shadow_pass, port->user_name, strlen(port->user_name), crypt_pwd2)) { pfree(crypt_pwd); pfree(crypt_pwd2); return STATUS_ERROR; } if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), port->md5Salt, sizeof(port->md5Salt), crypt_pwd)) { pfree(crypt_pwd); pfree(crypt_pwd2); return STATUS_ERROR; } pfree(crypt_pwd2); } break; default: if (isMD5(shadow_pass)) { /* Encrypt user-supplied password to match stored MD5 */ crypt_client_pass = palloc(MD5_PASSWD_LEN + 1); if (!pg_md5_encrypt(client_pass, port->user_name, strlen(port->user_name), crypt_client_pass)) { pfree(crypt_client_pass); return STATUS_ERROR; } } crypt_pwd = shadow_pass; break; } if (strcmp(crypt_client_pass, crypt_pwd) == 0) { /* * Password OK, now check to be sure we are not past rolvaliduntil */ if (isnull) retval = STATUS_OK; else if (vuntil < GetCurrentTimestamp()) { *logdetail = psprintf(_("User \"%s\" has an expired password."), role); retval = STATUS_ERROR; } else retval = STATUS_OK; } else *logdetail = psprintf(_("Password does not match for user \"%s\"."), role); if (port->hba->auth_method == uaMD5) pfree(crypt_pwd); if (crypt_client_pass != client_pass) pfree(crypt_client_pass); return retval; }
VOID PsSelectCustomPageSize( PDEVDATA pdev ) /*++ Routine Description: Generate PostScript code to select custom page size on the printer. Arguments: pdev Pointer to DEVDATA structure Return Value: NONE --*/ { PSREAL params[MAXPCP]; INT index; HPPD hppd = pdev->hppd; PSREAL xlen, ylen; // Sanity check: if no custom page size invocation is provided, // simply return with emitting anything. if (hppd->pCustomSizeCode == NULL) { DBGMSG(DBG_LEVEL_WARNING, "No invocation string for custom page size.\n"); return; } // Generate parameters for custom page size invocation // Sort them according to the order specified in PPD file for (index=0; index < MAXPCP; index++) params[index] = 0; // Figure out size of the physical page along x- and y-axis // // Undo the effect of AdjustForLandscape here: // in landscape mode, CurForm.PaperSize.width and // and CurForm.PaperSize.height were swapped. if (pdev->CurForm.bLandscape) { xlen = pdev->CurForm.PaperSize.height; ylen = pdev->CurForm.PaperSize.width; } else { xlen = pdev->CurForm.PaperSize.width; ylen = pdev->CurForm.PaperSize.height; } if (! hppd->bCutSheet) { PSREAL maxWidth, maxHeight, tmpPsreal; // For roll-fed devices, choose orientation 0 or 1 // depending on whether width is bigger than height maxWidth = hppd->maxMediaWidth - hppd->customParam[PCP_WIDTHOFFSET].minVal; maxHeight = hppd->maxMediaHeight - hppd->customParam[PCP_HEIGHTOFFSET].minVal; if (xlen <= ylen && ylen <= maxWidth && xlen <= maxHeight) { // Use orientation 0: ylen is used as width parameter // and xlen is used as height parameter if (hppd->customParam[PCP_ORIENTATION].minVal > 0) { DBGMSG(DBG_LEVEL_ERROR, "Device does not support orientation 0.\n"); } tmpPsreal = xlen; xlen = ylen; ylen = tmpPsreal; } else { // Use orientation 1 if (hppd->customParam[PCP_ORIENTATION].maxVal < 1) { DBGMSG(DBG_LEVEL_ERROR, "Device does not support orientation 1.\n"); } params[hppd->customParam[PCP_ORIENTATION].dwOrder - 1] = 1; } } params[hppd->customParam[PCP_WIDTH].dwOrder - 1] = xlen; params[hppd->customParam[PCP_HEIGHT].dwOrder - 1] = ylen; // Use minimum width and height offsets params[hppd->customParam[PCP_WIDTHOFFSET].dwOrder - 1] = hppd->customParam[PCP_WIDTHOFFSET].minVal; params[hppd->customParam[PCP_HEIGHTOFFSET].dwOrder - 1] = hppd->customParam[PCP_HEIGHTOFFSET].minVal; // Emit custom page size parameters and invocation string for (index=0; index < MAXPCP; index++) psprintf(pdev, "%f ", params[index]); psputs(pdev, hppd->pCustomSizeCode); psputs(pdev, "\n"); }
char * widget_out(WIDGET *widget) { return psprintf("(%g,%g,%g)", widget->center.x, widget->center.y, widget->radius); }
BOOL bOutput24bppBitmapAsMask( PDEVDATA pdev, SURFOBJ *psoSrc, PPOINTL pptlSrc, PRECTL prclDst) { RGBTRIPLE *prgbAlt = NULL; PBYTE pjStart,pjBits; int x,y; LONG cx,cy,xLeft,yTop; // compute the area to actualy draw, the smaller of the src or dest xLeft = max(0,pptlSrc->x); yTop = max(0,pptlSrc->y); cx = min(prclDst->right - prclDst->left,psoSrc->sizlBitmap.cx - xLeft); cy = min(prclDst->bottom - prclDst->top,psoSrc->sizlBitmap.cy - yTop); // first go over the bitmap to find the first non white pixel pjStart = (PBYTE)psoSrc->pvScan0 + xLeft * sizeof(RGBTRIPLE) + yTop * psoSrc->lDelta; pjBits = pjStart; for (y = yTop; (prgbAlt == NULL) && (y < (yTop + cy)); ++y, pjBits += psoSrc->lDelta) { RGBTRIPLE *prgb = (RGBTRIPLE*)pjBits; for (x = xLeft; x < (xLeft + cx); ++x, ++prgb) { if ((prgb->rgbtBlue & prgb->rgbtGreen & prgb->rgbtRed) != 0xff) { // found a non white pixel prgbAlt = prgb; break; } } } if (prgbAlt == NULL) return(TRUE); // prgbAlt now points to an RGB value for the alternate color. If we didn't // find an alternate color we use white. In the future for performance we could // replace the ROP by SRCCOPY. Not much reason to optimize for this case now // since it shouldn't happen // output the header information psputs(pdev, "gsave\n"); psprintf(pdev, "%d %d translate\n", prclDst->left, prclDst->top); psprintf(pdev, "%d %d scale\n", cx, cy); // r g b setrgbcolor psprintf(pdev, "%d 256 div ", prgbAlt->rgbtRed); psprintf(pdev, "%d 256 div ", prgbAlt->rgbtGreen); psprintf(pdev, "%d 256 div setrgbcolor\n", prgbAlt->rgbtBlue); psprintf(pdev, "/str2 %d string def\n", (cx+7) / 8); // size of mask psprintf(pdev, "%d %d", cx, cy); // paint the 0's, leave the 1's alone psputs(pdev, "\nfalse\n"); // [cx 0 0 cy 0 0] psprintf(pdev, "[%d 0 0 %d 0 0]\n", cx, cy); // get ready for the data psputs (pdev, "{currentfile str2 readhexstring pop}bind imagemask\n"); // Now go through the bitmap output ascii hex values for each byte of the mask. // 1's should be left alone, 0's should be set to the alternate color. pjBits = pjStart; for (y = yTop; y < (yTop + cy); ++y, pjBits += psoSrc->lDelta) { RGBTRIPLE *prgb = (RGBTRIPLE*)pjBits; int c = 0; for (x = xLeft; x < (xLeft + cx);) { BYTE jMask; int i; for (i = 0; (i < 8) && (x < (xLeft + cx)); ++i, ++x, ++prgb) { jMask <<= 1; if ((prgb->rgbtBlue & prgb->rgbtGreen & prgb->rgbtRed) == 0xff) { // non white pixel jMask |= 1; } } // if we got to the end without filling up the last byte, fill it with 1's jMask = (jMask << (8 - i)) | ajOrBits[i]; psputhex(pdev, 1, &jMask); // add a line feed every 80 bytes of data if ((c++ == 80) && (x < (xLeft + cx))) { c = 0; psputs(pdev,"\n"); } } psputs(pdev,"\n"); } // restore the state psputs(pdev,"grestore\n"); return(TRUE); }