static void Help(void) { PR_fprintf(err, "Usage: [-S] [-K <n>] [-h] <filename>\n"); PR_fprintf(err, "\t-c Nuber of iterations (default: 10)\n"); PR_fprintf(err, "\t-S Sync the file (default: FALSE)\n"); PR_fprintf(err, "\t-K Size of file (K bytes) (default: 10)\n"); PR_fprintf(err, "\t Name of file to write (default: /usr/tmp/sync.dat)\n"); PR_fprintf(err, "\t-h This message and nothing else\n"); } /* Help */
/************************************************************************** * * G e n e r a t e S e l f S i g n e d O b j e c t S i g n i n g C e r t * *phew*^ * */ static CERTCertificate* GenerateSelfSignedObjectSigningCert(char *nickname, CERTCertDBHandle *db, char *subject, unsigned long serial, int keysize, char *token) { CERTCertificate * cert, *temp_cert; SECItem * derCert; CERTCertificateRequest * req; PK11SlotInfo * slot = NULL; SECKEYPrivateKey * privk = NULL; SECKEYPublicKey * pubk = NULL; if ( token ) { slot = PK11_FindSlotByName(token); } else { slot = PK11_GetInternalKeySlot(); } if (slot == NULL) { PR_fprintf(errorFD, "Can't find PKCS11 slot %s\n", token ? token : ""); errorCount++; exit (ERRX); } if ( GenerateKeyPair(slot, &pubk, &privk, keysize) != SECSuccess) { FatalError("Error generating keypair."); } req = make_cert_request (subject, pubk); temp_cert = make_cert (req, serial, &req->subject); if (set_cert_type(temp_cert, NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA) != SECSuccess) { FatalError("Unable to set cert type"); } derCert = sign_cert (temp_cert, privk); cert = install_cert(db, derCert, nickname); if (ChangeTrustAttributes(db, cert, ",,uC") != SECSuccess) { FatalError("Unable to change trust on generated certificate"); } /* !!! Free memory ? !!! */ PK11_FreeSlot(slot); SECKEY_DestroyPrivateKey(privk); SECKEY_DestroyPublicKey(pubk); return cert; }
PRStatus TimelineInit(void) { char *timeStr; char *fileName; PRInt32 secs, msecs; PRFileDesc *fd; PRInt64 tmp1, tmp2; PRStatus status = PR_NewThreadPrivateIndex( &gTLSIndex, ThreadDestruct ); NS_WARN_IF_FALSE(status==0, "TimelineService could not allocate TLS storage."); timeStr = PR_GetEnv("NS_TIMELINE_INIT_TIME"); #ifdef XP_MAC initInterval = PR_IntervalNow(); #endif // NS_TIMELINE_INIT_TIME only makes sense for the main thread, so if it // exists, set it there. If not, let normal thread management code take // care of setting the init time. if (timeStr != NULL && 2 == PR_sscanf(timeStr, "%d.%d", &secs, &msecs)) { PRTime &initTime = GetThisThreadData()->initTime; LL_MUL(tmp1, (PRInt64)secs, 1000000); LL_MUL(tmp2, (PRInt64)msecs, 1000); LL_ADD(initTime, tmp1, tmp2); #ifdef XP_MAC initInterval -= PR_MicrosecondsToInterval( (PRUint32)(PR_Now() - initTime)); #endif } // Get the log file. #ifdef XP_MAC fileName = "timeline.txt"; #else fileName = PR_GetEnv("NS_TIMELINE_LOG_FILE"); #endif if (fileName != NULL && (fd = PR_Open(fileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666)) != NULL) { timelineFD = fd; PR_fprintf(fd, "NOTE: due to asynchrony, the indentation that you see does" " not necessarily correspond to nesting in the code.\n\n"); } // Runtime disable of timeline if (PR_GetEnv("NS_TIMELINE_ENABLE")) gTimelineDisabled = PR_FALSE; return PR_SUCCESS; }
static void PR_CALLBACK Notified(void *arg) { Shared *shared = (Shared*)arg; PRStatus status = PR_SUCCESS; while (PR_SUCCESS == status) { PR_Lock(shared->ml); while (shared->twiddle && (PR_SUCCESS == status)) status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); if (verbosity) PR_fprintf(debug_out, "+"); shared->twiddle = PR_TRUE; shared->next->twiddle = PR_FALSE; PR_NotifyCondVar(shared->next->cv); PR_Unlock(shared->ml); } } /* Notified */
static void PrintProgress(PRIntn line) { failed = failed || (should && !did); failed = failed || (!should && did); if (debug > 0) { #if defined(WIN16) printf( "@ line %d destructor should%s have been called and was%s\n", line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); #else PR_fprintf( fout, "@ line %d destructor should%s have been called and was%s\n", line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT")); #endif } } /* PrintProgress */
static void Help(void) { debug_out = PR_STDOUT; PR_fprintf( debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n"); PR_fprintf( debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); PR_fprintf( debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); } /* Help */
int Usage(void) { PRFileDesc *pr_stderr = PR_STDERR; PR_fprintf (pr_stderr, "ocspresp runs an internal selftest for OCSP response creation"); PR_fprintf (pr_stderr, "Usage:"); PR_fprintf (pr_stderr, "\tocspresp <dbdir> <CA-nick> <EE-nick> [-p <pass>] [-f <file>]\n"); PR_fprintf (pr_stderr, "\tdbdir: Find security databases in \"dbdir\"\n"); PR_fprintf (pr_stderr, "\tCA-nick: nickname of a trusted CA certificate with private key\n"); PR_fprintf (pr_stderr, "\tEE-nick: nickname of a entity cert issued by CA\n"); PR_fprintf (pr_stderr, "\t-p: a password for db\n"); PR_fprintf (pr_stderr, "\t-f: a filename containing the password for db\n"); return -1; }
/************************************************************************ * * g e t F l a g s F r o m S t r i n g * * Parses a mechanism list passed on the command line and converts it * to an unsigned long bitmask. * string is a colon-separated string of constants * array is an array of MaskStrings. * elements is the number of elements in array. */ static unsigned long getFlagsFromString(char *string, const MaskString array[], int elements) { unsigned long ret = 0; short i = 0; char *cp; char *buf; char *end; if (!string || !string[0]) { return ret; } /* Make a temporary copy of the string */ buf = PR_Malloc(strlen(string) + 1); if (!buf) { out_of_memory(); } strcpy(buf, string); /* Look at each element of the list passed in */ for (cp = buf; cp && *cp; cp = (end ? end + 1 : NULL)) { /* Look at the string up to the next colon */ end = strchr(cp, ':'); if (end) { *end = '\0'; } /* Find which element this is */ for (i = 0; i < elements; i++) { if (!PORT_Strcasecmp(cp, array[i].name)) { break; } } if (i == elements) { /* Skip a bogus string, but print a warning message */ PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp); continue; } ret |= array[i].mask; } PR_Free(buf); return ret; }
static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv) { Overlay_i si; Overlay_u ui; PLOptStatus os; PRBool bsi = PR_FALSE, bui = PR_FALSE; PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:"); err = PR_GetSpecialFD(PR_StandardError); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'i': /* signed integer */ si.i = (PRInt32)atoi(opt->value); bsi = PR_TRUE; break; case 'u': /* unsigned */ ui.i = (PRUint32)atoi(opt->value); bui = PR_TRUE; break; case 'h': /* user wants some guidance */ default: Help(); /* so give him an earful */ return 2; /* but not a lot else */ } } PL_DestroyOptState(opt); #if defined(HAVE_LONG_LONG) PR_fprintf(err, "We have long long\n"); #else PR_fprintf(err, "We don't have long long\n"); #endif if (bsi) { PR_fprintf(err, "Converting %ld: ", si.i); LL_I2L(si.l, si.i); PR_fprintf(err, "%lld\n", si.l); } if (bui) { PR_fprintf(err, "Converting %lu: ", ui.i); LL_I2L(ui.l, ui.i); PR_fprintf(err, "%llu\n", ui.l); } return 0; } /* main */
/* * j a r _ f i n d _ k e y _ t y p e * * Determine the key type for a given cert, which * should be rsaKey or dsaKey. Any error return 0. * */ static int jar_find_key_type (CERTCertificate *cert) { SECKEYPrivateKey * privk = NULL; KeyType keyType; /* determine its type */ privk = PK11_FindKeyByAnyCert (cert, &pwdata); if (privk == NULL) { PR_fprintf(errorFD, "warning - can't find private key for this cert\n"); warningCount++; return 0; } keyType = privk->keyType; SECKEY_DestroyPrivateKey (privk); return keyType; }
/* * Prints the contents of a PRHostEnt structure */ void PrintHostent(const PRHostEnt *he) { int i; int j; PR_fprintf(outFile, "h_name: %s\n", he->h_name); for (i = 0; he->h_aliases[i]; i++) { PR_fprintf(outFile, "h_aliases[%d]: %s\n", i, he->h_aliases[i]); } PR_fprintf(outFile, "h_addrtype: %d\n", he->h_addrtype); PR_fprintf(outFile, "h_length: %d\n", he->h_length); for (i = 0; he->h_addr_list[i]; i++) { PR_fprintf(outFile, "h_addr_list[%d]: ", i); for (j = 0; j < he->h_length; j++) { if (j != 0) PR_fprintf(outFile, "."); PR_fprintf(outFile, "%u", (unsigned char)he->h_addr_list[i][j]); } PR_fprintf(outFile, "\n"); } }
static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) { PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc"); PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE; err = PR_GetSpecialFD(PR_StandardError); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode (noop) */ break; case 'l': /* locks */ locks = PR_TRUE; break; case 'm': /* monitors */ monitors = PR_TRUE; break; case 'c': /* cached monitors */ cmonitors = PR_TRUE; break; case 'h': /* needs guidance */ default: Help(); return 2; } } PL_DestroyOptState(opt); ml = PR_NewLock(); if (locks) T1Lock(); if (monitors) T1Mon(); if (cmonitors) T1CMon(); PR_DestroyLock(ml); PR_fprintf(err, "Done!\n"); return 0; } /* main */
static PRUint32 ContentiousMonitor(PRUint32 loops) { PRStatus status; PRThread *thread = NULL; MonitorContentious_t * contention; PRIntervalTime rv, overhead, timein = PR_IntervalNow(); contention = PR_NEWZAP(MonitorContentious_t); contention->loops = loops; contention->overhead = 0; contention->ml = PR_NewMonitor(); contention->interval = contention_interval; thread = PR_CreateThread( PR_USER_THREAD, MonitorContender, contention, PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); PR_ASSERT(thread != NULL); overhead = PR_IntervalNow() - timein; while (contention->loops-- > 0) { PR_EnterMonitor(contention->ml); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); contention->contentious+= 1; contention->overhead += contention->interval; PR_Sleep(contention->interval); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(contention->ml); PR_ExitMonitor(contention->ml); } timein = PR_IntervalNow(); status = PR_JoinThread(thread); PR_DestroyMonitor(contention->ml); overhead += (PR_IntervalNow() - timein); rv = overhead + contention->overhead; if (verbosity) PR_fprintf( std_err, "Access ratio: %u to %u\n", contention->contentious, contention->contender); PR_Free(contention); return rv; } /* ContentiousMonitor */
static void TestNowOverhead(void) { PRTime timeout, timein; PRInt32 overhead, loops = 1000000; PRInt64 elapsed, per_call, ten23rd, ten26th; LL_I2L(ten23rd, 1000); LL_I2L(ten26th, 1000000); timein = PR_Now(); while (--loops > 0) timeout = PR_Now(); LL_SUB(elapsed, timeout, timein); LL_MUL(elapsed, elapsed, ten23rd); LL_DIV(per_call, elapsed, ten26th); LL_L2I(overhead, per_call); PR_fprintf( output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead); } /* TestNowOverhead */
static PRInt16 PR_CALLBACK MyPoll( PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) { PRInt16 my_flags, new_flags; PRFilePrivate *mine = (PRFilePrivate*)fd->secret; if (0 != (PR_POLL_READ & in_flags)) { /* client thinks he's reading */ switch (mine->rcvstate) { case rcv_send_credit: my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE; break; case rcv_data: case rcv_get_debit: my_flags = in_flags; default: break; } } else if (0 != (PR_POLL_WRITE & in_flags)) { /* client thinks he's writing */ switch (mine->xmtstate) { case xmt_recv_credit: my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ; break; case xmt_send_debit: case xmt_data: my_flags = in_flags; default: break; } } else PR_NOT_REACHED("How'd I get here?"); new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags); if (verbosity > chatty) PR_fprintf( logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n", in_flags, my_flags, *out_flags, new_flags); return new_flags; } /* MyPoll */
static PRBool MakeConfFile(const char *regfile, const nsCString &greHome, const GREProperty *aProperties, PRUint32 aPropertiesLen) { // If the file exists, don't create it again! if (access(regfile, R_OK) == 0) return PR_FALSE; PRBool ok = PR_TRUE; { // scope "fd" so that we can delete the file if something goes wrong AutoFDClose fd = PR_Open(regfile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664); if (!fd) return PR_FALSE; static const char kHeader[] = "# Registration file generated by xulrunner. Do not edit.\n\n" "[" GRE_BUILD_ID "]\n" "GRE_PATH="; if (PR_Write(fd, kHeader, sizeof(kHeader) - 1) != sizeof(kHeader) - 1) ok = PR_FALSE; if (PR_Write(fd, greHome.get(), greHome.Length()) != greHome.Length()) ok = PR_FALSE; for (PRUint32 i = 0; i < aPropertiesLen; ++i) { if (PR_fprintf(fd, "\n%s=%s", aProperties[i].property, aProperties[i].value) <= 0) ok = PR_FALSE; } PR_Write(fd, "\n", 1); } if (!ok) PR_Delete(regfile); return ok; }
xpti_InterfaceWriter(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg) { xptiInterfaceEntry* entry = ((xptiHashEntry*)hdr)->value; PRFileDesc* fd = (PRFileDesc*) arg; char iidStr[NSID_LENGTH]; entry->GetTheIID()->ToProvidedString(iidStr); const xptiTypelib& typelib = entry->GetTypelibRecord(); PRBool success = !!PR_fprintf(fd, "%d,%s,%s,%d,%d,%d\n", (int) number, entry->GetTheName(), iidStr, (int) typelib.GetFileIndex(), (int) (typelib.IsZip() ? typelib.GetZipItemIndex() : -1), (int) entry->GetScriptableFlag()); return success ? PL_DHASH_NEXT : PL_DHASH_STOP; }
/* * m a n i f e s t o _ x p i _ f n * * Called by pointer from SignArchive(), once for * each file within the directory. This function * is only used for adding to XPI compatible archive * */ static int manifesto_xpi_fn (char *relpath, char *basedir, char *reldir, char *filename, void *arg) { char fullname [FNSIZE]; if (verbosity >= 0) { PR_fprintf(outputFD, "--> %s\n", relpath); } /* extension matching */ if (extensionsGiven) { char *ext = PL_strrchr(relpath, '.'); if (!ext) return 0; if (!PL_HashTableLookup(extensions, ext)) return 0; } sprintf (fullname, "%s/%s", basedir, relpath); JzipAdd(fullname, relpath, zipfile, compression_level); return 0; }
static void long_usage (char *program_name) { PRFileDesc *pr_stderr; pr_stderr = PR_STDERR; synopsis (program_name); PR_fprintf (pr_stderr, "\nDecode encrypted passwords (and other data).\n"); PR_fprintf (pr_stderr, "This program reads in standard configuration files looking\n" "for base 64 encoded data. Data that looks like it's base 64 encode\n" "is decoded an passed to the NSS SDR code. If the decode and decrypt\n" "is successful, then decrypted data is outputted in place of the\n" "original base 64 data. If the decode or decrypt fails, the original\n" "data is written and the reason for failure is logged to the \n" "optional logfile.\n"); PR_fprintf (pr_stderr, " %-13s Read stream including encrypted data from " "\"read_file\"\n", "-i read_file"); PR_fprintf (pr_stderr, " %-13s Write results to \"write_file\"\n", "-o write_file"); PR_fprintf (pr_stderr, " %-13s Find security databases in \"dbdir\"\n", "-d dbdir"); PR_fprintf (pr_stderr, " %-13s Log failed decrypt/decode attempts to \"log_file\"\n", "-l log_file"); PR_fprintf (pr_stderr, " %-13s Token password\n", "-p pwd"); PR_fprintf (pr_stderr, " %-13s Password file\n", "-f pwfile"); }
/****************************************************************** * * m a k e _ c e r t _ r e q u e s t */ static CERTCertificateRequest* make_cert_request(char *subject, SECKEYPublicKey *pubk) { CERTName * subj; CERTSubjectPublicKeyInfo * spki; CERTCertificateRequest * req; /* Create info about public key */ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); if (!spki) { SECU_PrintError(progName, "unable to create subject public key"); exit (ERRX); } subj = CERT_AsciiToName (subject); if (subj == NULL) { FatalError("Invalid data in certificate description"); } /* Generate certificate request */ req = CERT_CreateCertificateRequest(subj, spki, 0); if (!req) { SECU_PrintError(progName, "unable to make certificate request"); exit (ERRX); } SECKEY_DestroySubjectPublicKeyInfo(spki); CERT_DestroyName(subj); if (verbosity >= 0) { PR_fprintf(outputFD, "certificate request generated\n"); } return req; }
Error RawAddModule(char *dbmodulespec, char *modulespec) { SECMODModule *module; SECMODModule *dbmodule; dbmodule = SECMOD_LoadModule(dbmodulespec, NULL, PR_TRUE); if (dbmodule == NULL) { /* handle error */ return NO_SUCH_MODULE_ERR; } module = SECMOD_LoadModule(modulespec, dbmodule, PR_FALSE); if (module == NULL) { /* handle error */ return NO_SUCH_MODULE_ERR; } if (SECMOD_UpdateModule(module) != SECSuccess) { PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec); return UPDATE_MOD_FAILED_ERR; } return SUCCESS; }
static void long_usage (char *program_name) { synopsis (program_name); PR_fprintf (pr_stderr, "\nSecret Decoder Test:\n"); PR_fprintf (pr_stderr, " %-13s Read encrypted data from \"file\"\n", "-i file"); PR_fprintf (pr_stderr, " %-13s Write newly generated encrypted data to \"file\"\n", "-o file"); PR_fprintf (pr_stderr, " %-13s Use \"text\" as the plaintext for encryption and verification\n", "-t text"); PR_fprintf (pr_stderr, " %-13s Find security databases in \"dbdir\"\n", "-d dbdir"); PR_fprintf (pr_stderr, " %-13s read the password from \"pwfile\"\n", "-f pwfile"); PR_fprintf (pr_stderr, " %-13s supply \"password\" on the command line\n", "-p password"); }
int main(int argc, char **argv) { CERTCertDBHandle *certHandle; PRFileDesc *inFile; PRFileDesc *inCrlInitFile = NULL; int generateCRL; int modifyCRL; int listCRL; int importCRL; int showFileCRL; int deleteCRL; int rv; char *nickName; char *url; char *dbPrefix = ""; char *alg = NULL; char *outFile = NULL; char *slotName = NULL; int ascii = 0; int crlType; PLOptState *optstate; PLOptStatus status; SECStatus secstatus; PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS; PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS; PRBool quiet = PR_FALSE; PRBool test = PR_FALSE; PRBool erase = PR_FALSE; PRInt32 i = 0; PRInt32 iterations = 1; PRBool readonly = PR_FALSE; secuPWData pwdata = { PW_NONE, 0 }; progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; rv = 0; deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = showFileCRL = 0; inFile = NULL; nickName = url = NULL; certHandle = NULL; crlType = SEC_CRL_TYPE; /* * Parse command line arguments */ optstate = PL_CreateOptState(argc, argv, "sqBCDGILMSTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': Usage(progName); break; case 'T': test = PR_TRUE; break; case 'E': erase = PR_TRUE; break; case 'B': importOptions |= CRL_IMPORT_BYPASS_CHECKS; break; case 'G': generateCRL = 1; break; case 'M': modifyCRL = 1; break; case 'D': deleteCRL = 1; break; case 'I': importCRL = 1; break; case 'S': showFileCRL = 1; break; case 'C': case 'L': listCRL = 1; break; case 'P': dbPrefix = strdup(optstate->value); break; case 'Z': alg = strdup(optstate->value); break; case 'a': ascii = 1; break; case 'c': inCrlInitFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!inCrlInitFile) { PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); PL_DestroyOptState(optstate); return -1; } break; case 'd': SECU_ConfigDirectory(optstate->value); break; case 'f': pwdata.source = PW_FROMFILE; pwdata.data = strdup(optstate->value); break; case 'h': slotName = strdup(optstate->value); break; case 'i': inFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!inFile) { PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); PL_DestroyOptState(optstate); return -1; } break; case 'n': nickName = strdup(optstate->value); break; case 'o': outFile = strdup(optstate->value); break; case 'p': decodeOptions |= CRL_DECODE_SKIP_ENTRIES; break; case 'r': { const char* str = optstate->value; if (str && atoi(str)>0) iterations = atoi(str); } break; case 't': { crlType = atoi(optstate->value); if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) { PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName); PL_DestroyOptState(optstate); return -1; } break; case 'q': quiet = PR_TRUE; break; case 'w': pwdata.source = PW_PLAINTEXT; pwdata.data = strdup(optstate->value); break; case 'u': url = strdup(optstate->value); break; } } } PL_DestroyOptState(optstate); if (deleteCRL && !nickName) Usage (progName); if (importCRL && !inFile) Usage (progName); if (showFileCRL && !inFile) Usage (progName); if ((generateCRL && !nickName) || (modifyCRL && !inFile && !nickName)) Usage (progName); if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL || modifyCRL || test || erase)) Usage (progName); if (listCRL || showFileCRL) { readonly = PR_TRUE; } PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); PK11_SetPasswordFunc(SECU_GetModulePassword); if (showFileCRL) { NSS_NoDB_Init(NULL); } else { secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix, "secmod.db", readonly ? NSS_INIT_READONLY : 0); if (secstatus != SECSuccess) { SECU_PrintPRandOSError(progName); return -1; } } SECU_RegisterDynamicOids(); certHandle = CERT_GetDefaultCertDB(); if (certHandle == NULL) { SECU_PrintError(progName, "unable to open the cert db"); /*ignoring return value of NSS_Shutdown() as code returns -1*/ (void) NSS_Shutdown(); return (-1); } CRLGEN_InitCrlGenParserLock(); for (i=0; i<iterations; i++) { /* Read in the private key info */ if (deleteCRL) DeleteCRL (certHandle, nickName, crlType); else if (listCRL) { rv = ListCRL (certHandle, nickName, crlType); } else if (importCRL) { rv = ImportCRL (certHandle, url, crlType, inFile, importOptions, decodeOptions, &pwdata); } else if (showFileCRL) { rv = DumpCRL (inFile); } else if (generateCRL || modifyCRL) { if (!inCrlInitFile) inCrlInitFile = PR_STDIN; rv = GenerateCRL (certHandle, nickName, inCrlInitFile, inFile, outFile, ascii, slotName, importOptions, alg, quiet, decodeOptions, url, &pwdata, modifyCRL); } else if (erase) { /* list and delete all CRLs */ ListCRLNames (certHandle, crlType, PR_TRUE); } #ifdef DEBUG else if (test) { /* list and delete all CRLs */ ListCRLNames (certHandle, crlType, PR_TRUE); /* list CRLs */ ListCRLNames (certHandle, crlType, PR_FALSE); /* import CRL as a blob */ rv = ImportCRL (certHandle, url, crlType, inFile, importOptions, decodeOptions, &pwdata); /* list CRLs */ ListCRLNames (certHandle, crlType, PR_FALSE); } #endif } CRLGEN_DestroyCrlGenParserLock(); if (NSS_Shutdown() != SECSuccess) { rv = SECFailure; } return (rv != SECSuccess); }
int main (int argc, char **argv) { int retval; PRFileDesc *in_file; FILE *out_file; /* not PRFileDesc until SECU accepts it */ int crequest, dresponse; int prequest, presponse; int ccert, vcert; const char *db_dir, *date_str, *cert_usage_str, *name; const char *responder_name, *responder_url, *signer_name; PRBool add_acceptable_responses, add_service_locator; SECItem *data = NULL; PLOptState *optstate; SECStatus rv; CERTCertDBHandle *handle = NULL; SECCertUsage cert_usage; PRTime verify_time; CERTCertificate *cert = NULL; PRBool ascii = PR_FALSE; retval = -1; /* what we return/exit with on error */ program_name = PL_strrchr(argv[0], '/'); program_name = program_name ? (program_name + 1) : argv[0]; in_file = PR_STDIN; out_file = stdout; crequest = 0; dresponse = 0; prequest = 0; presponse = 0; ccert = 0; vcert = 0; db_dir = NULL; date_str = NULL; cert_usage_str = NULL; name = NULL; responder_name = NULL; responder_url = NULL; signer_name = NULL; add_acceptable_responses = PR_FALSE; add_service_locator = PR_FALSE; optstate = PL_CreateOptState (argc, argv, "AHLPR:S:V:d:l:pr:s:t:u:w:"); if (optstate == NULL) { SECU_PrintError (program_name, "PL_CreateOptState failed"); return retval; } while (PL_GetNextOpt (optstate) == PL_OPT_OK) { switch (optstate->option) { case '?': short_usage (program_name); return retval; case 'A': add_acceptable_responses = PR_TRUE; break; case 'H': long_usage (program_name); return retval; case 'L': add_service_locator = PR_TRUE; break; case 'P': presponse = 1; break; case 'R': dresponse = 1; name = optstate->value; break; case 'S': ccert = 1; name = optstate->value; break; case 'V': vcert = 1; name = optstate->value; break; case 'a': ascii = PR_TRUE; break; case 'd': db_dir = optstate->value; break; case 'l': responder_url = optstate->value; break; case 'p': prequest = 1; break; case 'r': crequest = 1; name = optstate->value; break; case 's': signer_name = optstate->value; break; case 't': responder_name = optstate->value; break; case 'u': cert_usage_str = optstate->value; break; case 'w': date_str = optstate->value; break; } } PL_DestroyOptState(optstate); if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) { PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n", program_name); short_usage (program_name); return retval; } if (vcert) { if (cert_usage_str == NULL) { PR_fprintf (PR_STDERR, "%s: verification requires cert usage\n\n", program_name); short_usage (program_name); return retval; } rv = cert_usage_from_char (cert_usage_str, &cert_usage); if (rv != SECSuccess) { PR_fprintf (PR_STDERR, "%s: invalid cert usage (\"%s\")\n\n", program_name, cert_usage_str); long_usage (program_name); return retval; } } if (ccert + vcert) { if (responder_url != NULL || responder_name != NULL) { /* * To do a full status check, both the URL and the cert name * of the responder must be specified if either one is. */ if (responder_url == NULL || responder_name == NULL) { if (responder_url == NULL) PR_fprintf (PR_STDERR, "%s: must also specify responder location\n\n", program_name); else PR_fprintf (PR_STDERR, "%s: must also specify responder name\n\n", program_name); short_usage (program_name); return retval; } } if (date_str != NULL) { rv = DER_AsciiToTime (&verify_time, (char *) date_str); if (rv != SECSuccess) { SECU_PrintError (program_name, "error converting time string"); PR_fprintf (PR_STDERR, "\n"); long_usage (program_name); return retval; } } else { verify_time = PR_Now(); } } retval = -2; /* errors change from usage to runtime */ /* * Initialize the NSPR and Security libraries. */ PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); db_dir = SECU_ConfigDirectory (db_dir); rv = NSS_Init (db_dir); if (rv != SECSuccess) { SECU_PrintError (program_name, "NSS_Init failed"); goto prdone; } SECU_RegisterDynamicOids(); if (prequest + presponse) { MAKE_FILE_BINARY(stdin); data = read_file_into_item (in_file, siBuffer); if (data == NULL) { SECU_PrintError (program_name, "problem reading input"); goto nssdone; } } if (crequest + dresponse + presponse + ccert + vcert) { handle = CERT_GetDefaultCertDB(); if (handle == NULL) { SECU_PrintError (program_name, "problem getting certdb handle"); goto nssdone; } /* * It would be fine to do the enable for all of these commands, * but this way we check that everything but an overall verify * can be done without it. That is, that the individual pieces * work on their own. */ if (vcert) { rv = CERT_EnableOCSPChecking (handle); if (rv != SECSuccess) { SECU_PrintError (program_name, "error enabling OCSP checking"); goto nssdone; } } if ((ccert + vcert) && (responder_name != NULL)) { rv = CERT_SetOCSPDefaultResponder (handle, responder_url, responder_name); if (rv != SECSuccess) { SECU_PrintError (program_name, "error setting default responder"); goto nssdone; } rv = CERT_EnableOCSPDefaultResponder (handle); if (rv != SECSuccess) { SECU_PrintError (program_name, "error enabling default responder"); goto nssdone; } } } #define NOTYET(opt) \ { \ PR_fprintf (PR_STDERR, "%s not yet working\n", opt); \ exit (-1); \ } if (name) { cert = find_certificate(handle, name, ascii); } if (crequest) { if (signer_name != NULL) { NOTYET("-s"); } rv = create_request (out_file, handle, cert, add_service_locator, add_acceptable_responses); } else if (dresponse) { if (signer_name != NULL) { NOTYET("-s"); } rv = dump_response (out_file, handle, cert, responder_url); } else if (prequest) { rv = print_request (out_file, data); } else if (presponse) { rv = print_response (out_file, data, handle); } else if (ccert) { if (signer_name != NULL) { NOTYET("-s"); } rv = get_cert_status (out_file, handle, cert, name, verify_time); } else if (vcert) { if (signer_name != NULL) { NOTYET("-s"); } rv = verify_cert (out_file, handle, cert, name, cert_usage, verify_time); } if (rv != SECSuccess) SECU_PrintError (program_name, "error performing requested operation"); else retval = 0; nssdone: if (cert) { CERT_DestroyCertificate(cert); } if (data != NULL) { SECITEM_FreeItem (data, PR_TRUE); } if (handle != NULL) { CERT_DisableOCSPDefaultResponder(handle); CERT_DisableOCSPChecking (handle); } if (NSS_Shutdown () != SECSuccess) { retval = 1; } prdone: PR_Cleanup (); return retval; }
static void long_usage (char *program_name) { PRFileDesc *pr_stderr; pr_stderr = PR_STDERR; synopsis (program_name); PR_fprintf (pr_stderr, "\nCommands (must specify exactly one):\n"); PR_fprintf (pr_stderr, " %-13s Pretty-print a binary request read from stdin\n", "-p"); PR_fprintf (pr_stderr, " %-13s Pretty-print a binary response read from stdin\n", "-P"); PR_fprintf (pr_stderr, " %-13s Create a request for cert \"nickname\" on stdout\n", "-r nickname"); PR_fprintf (pr_stderr, " %-13s Get response for cert \"nickname\", dump to stdout\n", "-R nickname"); PR_fprintf (pr_stderr, " %-13s Get status for cert \"nickname\"\n", "-S nickname"); PR_fprintf (pr_stderr, " %-13s Fully verify cert \"nickname\", w/ status check\n", "-V nickname"); PR_fprintf (pr_stderr, "\n %-10s also can be the name of the file with DER or\n" " %-13s PEM(use -a option) cert encoding\n", "nickname", ""); PR_fprintf (pr_stderr, "Options:\n"); PR_fprintf (pr_stderr, " %-13s Decode input cert from PEM format. DER is default\n", "-a"); PR_fprintf (pr_stderr, " %-13s Add the service locator extension to the request\n", "-L"); PR_fprintf (pr_stderr, " %-13s Find security databases in \"dbdir\" (default %s)\n", "-d dbdir", DEFAULT_DB_DIR); PR_fprintf (pr_stderr, " %-13s Use \"location\" as URL of responder\n", "-l location"); PR_fprintf (pr_stderr, " %-13s Trust cert \"nickname\" as response signer\n", "-t nickname"); PR_fprintf (pr_stderr, " %-13s Sign requests with cert \"nickname\"\n", "-s nickname"); PR_fprintf (pr_stderr, " %-13s Type of certificate usage for verification:\n", "-u usage"); PR_fprintf (pr_stderr, "%-17s c SSL Client\n", ""); PR_fprintf (pr_stderr, "%-17s s SSL Server\n", ""); PR_fprintf (pr_stderr, "%-17s e Email Recipient\n", ""); PR_fprintf (pr_stderr, "%-17s E Email Signer\n", ""); PR_fprintf (pr_stderr, "%-17s S Object Signer\n", ""); PR_fprintf (pr_stderr, "%-17s C CA\n", ""); PR_fprintf (pr_stderr, " %-13s Validity time (default current time), one of:\n", "-w time"); PR_fprintf (pr_stderr, "%-17s %-25s (GMT)\n", "", "YYMMDDhhmm[ss]Z"); PR_fprintf (pr_stderr, "%-17s %-25s (later than GMT)\n", "", "YYMMDDhhmm[ss]+hhmm"); PR_fprintf (pr_stderr, "%-17s %-25s (earlier than GMT)\n", "", "YYMMDDhhmm[ss]-hhmm"); }
/********************************************************************* * * m a i n */ int main(int argc, char *argv[]) { PRBool readOnly; int retval = 0; outputFD = PR_STDOUT; errorFD = PR_STDERR; progName = argv[0]; if (argc < 2) { Usage(); } excludeDirs = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); extensions = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); if (parse_args(argc, argv)) { retval = -1; goto cleanup; } /* Parse the command file if one was given */ if (cmdFile) { if (ProcessCommandFile()) { retval = -1; goto cleanup; } } /* Set up output redirection */ if (outfile) { if (PR_Access(outfile, PR_ACCESS_EXISTS) == PR_SUCCESS) { /* delete the file if it is already present */ PR_fprintf(errorFD, "warning: %s already exists and will be overwritten.\n", outfile); warningCount++; if (PR_Delete(outfile) != PR_SUCCESS) { PR_fprintf(errorFD, "ERROR: unable to delete %s.\n", outfile); errorCount++; exit(ERRX); } } outputFD = PR_Open(outfile, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777); if (!outputFD) { PR_fprintf(errorFD, "ERROR: Unable to create %s.\n", outfile); errorCount++; exit(ERRX); } errorFD = outputFD; } /* This seems to be a fairly common user error */ if (verify && list_certs > 0) { PR_fprintf(errorFD, "%s: Can't use -l and -v at the same time\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -J assumes -Z now */ if (javascript && zipfile) { PR_fprintf(errorFD, "%s: Can't use -J and -Z at the same time\n", PROGRAM_NAME); PR_fprintf(errorFD, "%s: -J option will create the jar files for you\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -X needs -Z */ if (xpi_arc && !zipfile) { PR_fprintf(errorFD, "%s: option XPI (-X) requires option jarfile (-Z)\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* Less common mixing of -L with various options */ if (list_certs > 0 && (tell_who || zipfile || javascript || scriptdir || extensionsGiven || exclusionsGiven || install_script)) { PR_fprintf(errorFD, "%s: Can't use -l or -L with that option\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } if (!cert_dir) cert_dir = get_default_cert_dir(); VerifyCertDir(cert_dir, keyName); if (compression_level < MIN_COMPRESSION_LEVEL || compression_level > MAX_COMPRESSION_LEVEL) { PR_fprintf(errorFD, "Compression level must be between %d and %d.\n", MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL); errorCount++; retval = -1; goto cleanup; } if (jartree && !keyName) { PR_fprintf(errorFD, "You must specify a key with which to sign.\n"); errorCount++; retval = -1; goto cleanup; } readOnly = (genkey == NULL); /* only key generation requires write */ if (InitCrypto(cert_dir, readOnly)) { PR_fprintf(errorFD, "ERROR: Cryptographic initialization failed.\n"); errorCount++; retval = -1; goto cleanup; } if (enableOCSP) { SECStatus rv = CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); if (rv != SECSuccess) { PR_fprintf(errorFD, "ERROR: Attempt to enable OCSP Checking failed.\n"); errorCount++; retval = -1; } } if (verify) { if (VerifyJar(verify)) { errorCount++; retval = -1; goto cleanup; } } else if (list_certs) { if (ListCerts(keyName, list_certs)) { errorCount++; retval = -1; goto cleanup; } } else if (list_modules) { JarListModules(); } else if (genkey) { if (GenerateCert(genkey, keySize, token)) { errorCount++; retval = -1; goto cleanup; } } else if (tell_who) { if (JarWho(tell_who)) { errorCount++; retval = -1; goto cleanup; } } else if (javascript && jartree) { /* make sure directory exists */ PRDir *dir; dir = PR_OpenDir(jartree); if (!dir) { PR_fprintf(errorFD, "ERROR: unable to open directory %s.\n", jartree); errorCount++; retval = -1; goto cleanup; } else { PR_CloseDir(dir); } /* undo junk from prior runs of signtool*/ if (RemoveAllArc(jartree)) { PR_fprintf(errorFD, "Error removing archive directories under %s\n", jartree); errorCount++; retval = -1; goto cleanup; } /* traverse all the htm|html files in the directory */ if (InlineJavaScript(jartree, !noRecurse)) { retval = -1; goto cleanup; } /* sign any resultant .arc directories created in above step */ if (SignAllArc(jartree, keyName, javascript, metafile, install_script, optimize, !noRecurse)) { retval = -1; goto cleanup; } if (!leaveArc) { RemoveAllArc(jartree); } if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); } } else if (jartree) { SignArchive(jartree, keyName, zipfile, javascript, metafile, install_script, optimize, !noRecurse); } else Usage(); cleanup: if (extensions) { PL_HashTableDestroy(extensions); extensions = NULL; } if (excludeDirs) { PL_HashTableDestroy(excludeDirs); excludeDirs = NULL; } if (outputFD != PR_STDOUT) { PR_Close(outputFD); } rm_dash_r(TMP_OUTPUT); if (retval == 0) { if (NSS_Shutdown() != SECSuccess) { exit(1); } } return retval; }
/********************************************************************* * * P r o c e s s O n e O p t * * Since options can come from different places (command file, word options, * char options), this is a central function that is called to deal with * them no matter where they come from. * * type is the type of option. * arg is the argument to the option, possibly NULL. * Returns 1 if the argument was eaten, 0 if it wasn't, and -1 for error. */ static int ProcessOneOpt(OPT_TYPE type, char *arg) { int ate = 0; switch (type) { case HELP_OPT: Usage(); break; case LONG_HELP_OPT: LongUsage(); break; case BASE_OPT: if (base) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-b"); warningCount++; PR_Free(base); base = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-b"); errorCount++; goto loser; } base = PL_strdup(arg); ate = 1; break; case COMPRESSION_OPT: if (compression_level_specified) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-c"); warningCount++; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-c"); errorCount++; goto loser; } compression_level = atoi(arg); compression_level_specified = PR_TRUE; ate = 1; break; case CERT_DIR_OPT: if (cert_dir) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-d"); warningCount++; PR_Free(cert_dir); cert_dir = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-d"); errorCount++; goto loser; } cert_dir = PL_strdup(arg); ate = 1; break; case EXTENSION_OPT: if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "extension (-e)"); errorCount++; goto loser; } PL_HashTableAdd(extensions, arg, arg); extensionsGiven = PR_TRUE; ate = 1; break; case INSTALL_SCRIPT_OPT: if (install_script) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "installScript (-i)"); warningCount++; PR_Free(install_script); install_script = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "installScript (-i)"); errorCount++; goto loser; } install_script = PL_strdup(arg); ate = 1; break; case SCRIPTDIR_OPT: if (scriptdir) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "javascriptdir (-j)"); warningCount++; PR_Free(scriptdir); scriptdir = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "javascriptdir (-j)"); errorCount++; goto loser; } scriptdir = PL_strdup(arg); ate = 1; break; case CERTNAME_OPT: if (keyName) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "keyName (-k)"); warningCount++; PR_Free(keyName); keyName = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "keyName (-k)"); errorCount++; goto loser; } keyName = PL_strdup(arg); ate = 1; break; case LIST_OBJSIGN_CERTS_OPT: case LIST_ALL_CERTS_OPT: if (list_certs != 0) { PR_fprintf(errorFD, "warning: only one of -l and -L may be specified.\n"); warningCount++; } list_certs = (type == LIST_OBJSIGN_CERTS_OPT ? 1 : 2); break; case METAFILE_OPT: if (metafile) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "metafile (-m)"); warningCount++; PR_Free(metafile); metafile = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "metafile (-m)"); errorCount++; goto loser; } metafile = PL_strdup(arg); ate = 1; break; case OPTIMIZE_OPT: optimize = 1; break; case ENABLE_OCSP_OPT: enableOCSP = 1; break; case PASSWORD_OPT: if (pwdata.data) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "password (-p)"); warningCount++; PR_Free(pwdata.data); pwdata.data = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "password (-p)"); errorCount++; goto loser; } pwdata.source = PW_PLAINTEXT; pwdata.data = PL_strdup(arg); ate = 1; break; case VERIFY_OPT: if (verify) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "verify (-v)"); warningCount++; PR_Free(verify); verify = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "verify (-v)"); errorCount++; goto loser; } verify = PL_strdup(arg); ate = 1; break; case WHO_OPT: if (tell_who) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "who (-v)"); warningCount++; PR_Free(tell_who); tell_who = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "who (-w)"); errorCount++; goto loser; } tell_who = PL_strdup(arg); ate = 1; break; case EXCLUDE_OPT: if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "exclude (-x)"); errorCount++; goto loser; } PL_HashTableAdd(excludeDirs, arg, arg); exclusionsGiven = PR_TRUE; ate = 1; break; case NO_TIME_OPT: no_time = 1; break; case JAVASCRIPT_OPT: javascript++; break; case ZIPFILE_OPT: if (zipfile) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "jarfile (-Z)"); warningCount++; PR_Free(zipfile); zipfile = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "jarfile (-Z)"); errorCount++; goto loser; } zipfile = PL_strdup(arg); ate = 1; break; case GENKEY_OPT: if (genkey) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "generate (-G)"); warningCount++; PR_Free(genkey); genkey = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "generate (-G)"); errorCount++; goto loser; } genkey = PL_strdup(arg); ate = 1; break; case MODULES_OPT: list_modules++; break; case SIGNDIR_OPT: if (jartree) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "signdir"); warningCount++; PR_Free(jartree); jartree = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "signdir"); errorCount++; goto loser; } jartree = PL_strdup(arg); ate = 1; break; case OUTFILE_OPT: if (outfile) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "outfile"); warningCount++; PR_Free(outfile); outfile = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "outfile"); errorCount++; goto loser; } outfile = PL_strdup(arg); ate = 1; break; case COMMAND_FILE_OPT: if (cmdFile) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-f"); warningCount++; PR_Free(cmdFile); cmdFile = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-f"); errorCount++; goto loser; } cmdFile = PL_strdup(arg); ate = 1; break; case NORECURSE_OPT: noRecurse = PR_TRUE; break; case LEAVE_ARC_OPT: leaveArc = PR_TRUE; break; case VERBOSITY_OPT: if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "--verbosity"); errorCount++; goto loser; } verbosity = atoi(arg); ate = 1; break; case KEYSIZE_OPT: if (keySize != -1) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-s"); warningCount++; } keySize = atoi(arg); ate = 1; if (keySize < 1 || keySize > MAX_RSA_KEY_SIZE) { PR_fprintf(errorFD, "Invalid key size: %d.\n", keySize); errorCount++; goto loser; } break; case TOKEN_OPT: if (token) { PR_fprintf(errorFD, errStrings[DUPLICATE_OPTION_ERR], "-t"); PR_Free(token); token = NULL; } if (!arg) { PR_fprintf(errorFD, errStrings[OPTION_NEEDS_ARG_ERR], "-t"); errorCount++; goto loser; } token = PL_strdup(arg); ate = 1; break; case XPI_ARC_OPT: xpi_arc = 1; break; default: PR_fprintf(errorFD, "warning: unknown option\n"); warningCount++; break; } return ate; loser: return -1; }
/********************************************************************* * * p a r s e _ a r g s */ static int parse_args(int argc, char *argv[]) { char *opt; char *arg; int needsInc = 0; int i; OPT_TYPE type; /* Loop over all arguments */ for (i = 1; i < argc; i++) { opt = argv[i]; arg = NULL; if (opt[0] == '-') { if (opt[1] == '-') { /* word option */ if (i < argc - 1) { needsInc = 1; arg = argv[i + 1]; } else { arg = NULL; } if (!PL_strcasecmp(opt + 2, "norecurse")) { type = NORECURSE_OPT; } else if (!PL_strcasecmp(opt + 2, "leavearc")) { type = LEAVE_ARC_OPT; } else if (!PL_strcasecmp(opt + 2, "verbosity")) { type = VERBOSITY_OPT; } else if (!PL_strcasecmp(opt + 2, "outfile")) { type = OUTFILE_OPT; } else if (!PL_strcasecmp(opt + 2, "keysize")) { type = KEYSIZE_OPT; } else if (!PL_strcasecmp(opt + 2, "token")) { type = TOKEN_OPT; } else { PR_fprintf(errorFD, "warning: unknown option: %s\n", opt); warningCount++; type = UNKNOWN_OPT; } } else { /* char option */ if (opt[2] != '\0') { arg = opt + 2; } else if (i < argc - 1) { needsInc = 1; arg = argv[i + 1]; } else { arg = NULL; } switch (opt[1]) { case 'b': type = BASE_OPT; break; case 'c': type = COMPRESSION_OPT; break; case 'd': type = CERT_DIR_OPT; break; case 'e': type = EXTENSION_OPT; break; case 'f': type = COMMAND_FILE_OPT; break; case 'h': type = HELP_OPT; break; case 'H': type = LONG_HELP_OPT; break; case 'i': type = INSTALL_SCRIPT_OPT; break; case 'j': type = SCRIPTDIR_OPT; break; case 'k': type = CERTNAME_OPT; break; case 'l': type = LIST_OBJSIGN_CERTS_OPT; break; case 'L': type = LIST_ALL_CERTS_OPT; break; case 'm': type = METAFILE_OPT; break; case 'o': type = OPTIMIZE_OPT; break; case 'O': type = ENABLE_OCSP_OPT; break; case 'p': type = PASSWORD_OPT; break; case 'v': type = VERIFY_OPT; break; case 'w': type = WHO_OPT; break; case 'x': type = EXCLUDE_OPT; break; case 'X': type = XPI_ARC_OPT; break; case 'z': type = NO_TIME_OPT; break; case 'J': type = JAVASCRIPT_OPT; break; case 'Z': type = ZIPFILE_OPT; break; case 'G': type = GENKEY_OPT; break; case 'M': type = MODULES_OPT; break; case 's': type = KEYSIZE_OPT; break; case 't': type = TOKEN_OPT; break; default: type = UNKNOWN_OPT; PR_fprintf(errorFD, "warning: unrecognized option: -%c.\n", opt[1]); warningCount++; break; } } } else { type = UNKNOWN_OPT; if (i == argc - 1) { if (jartree) { PR_fprintf(errorFD, "warning: directory to be signed specified more than once.\n" " Only last specification will be used.\n"); warningCount++; PR_Free(jartree); jartree = NULL; } jartree = PL_strdup(opt); } else { PR_fprintf(errorFD, "warning: unrecognized option: %s\n", opt); warningCount++; } } if (type != UNKNOWN_OPT) { short ateArg = ProcessOneOpt(type, arg); if (ateArg == -1) { /* error */ return -1; } if (ateArg && needsInc) { i++; } } } return 0; }
/********************************************************************* * * P r o c e s s C o m m a n d F i l e */ int ProcessCommandFile() { PRFileDesc *fd; #define CMD_FILE_BUFSIZE 1024 char buf[CMD_FILE_BUFSIZE]; char *equals; int linenum = 0; int retval = -1; OPT_TYPE type; fd = PR_Open(cmdFile, PR_RDONLY, 0777); if (!fd) { PR_fprintf(errorFD, "ERROR: Unable to open command file %s.\n"); errorCount++; return -1; } while (pr_fgets(buf, CMD_FILE_BUFSIZE, fd)) { char *eol; linenum++; /* Chop off final newline */ eol = PL_strchr(buf, '\r'); if (!eol) { eol = PL_strchr(buf, '\n'); } if (eol) *eol = '\0'; equals = PL_strchr(buf, '='); if (!equals) { continue; } *equals = '\0'; equals++; /* Now buf points to the attribute, and equals points to the value. */ /* This is pretty straightforward, just deal with whatever attribute * this is */ if (!PL_strcasecmp(buf, "basename")) { type = BASE_OPT; } else if (!PL_strcasecmp(buf, "compression")) { type = COMPRESSION_OPT; } else if (!PL_strcasecmp(buf, "certdir")) { type = CERT_DIR_OPT; } else if (!PL_strcasecmp(buf, "extension")) { type = EXTENSION_OPT; } else if (!PL_strcasecmp(buf, "generate")) { type = GENKEY_OPT; } else if (!PL_strcasecmp(buf, "installScript")) { type = INSTALL_SCRIPT_OPT; } else if (!PL_strcasecmp(buf, "javascriptdir")) { type = SCRIPTDIR_OPT; } else if (!PL_strcasecmp(buf, "htmldir")) { type = JAVASCRIPT_OPT; if (jartree) { PR_fprintf(errorFD, "warning: directory to be signed specified more than once." " Only last specification will be used.\n"); warningCount++; PR_Free(jartree); jartree = NULL; } jartree = PL_strdup(equals); } else if (!PL_strcasecmp(buf, "certname")) { type = CERTNAME_OPT; } else if (!PL_strcasecmp(buf, "signdir")) { type = SIGNDIR_OPT; } else if (!PL_strcasecmp(buf, "list")) { type = LIST_OBJSIGN_CERTS_OPT; } else if (!PL_strcasecmp(buf, "listall")) { type = LIST_ALL_CERTS_OPT; } else if (!PL_strcasecmp(buf, "metafile")) { type = METAFILE_OPT; } else if (!PL_strcasecmp(buf, "modules")) { type = MODULES_OPT; } else if (!PL_strcasecmp(buf, "optimize")) { type = OPTIMIZE_OPT; } else if (!PL_strcasecmp(buf, "ocsp")) { type = ENABLE_OCSP_OPT; } else if (!PL_strcasecmp(buf, "password")) { type = PASSWORD_OPT; } else if (!PL_strcasecmp(buf, "verify")) { type = VERIFY_OPT; } else if (!PL_strcasecmp(buf, "who")) { type = WHO_OPT; } else if (!PL_strcasecmp(buf, "exclude")) { type = EXCLUDE_OPT; } else if (!PL_strcasecmp(buf, "notime")) { type = NO_TIME_OPT; } else if (!PL_strcasecmp(buf, "jarfile")) { type = ZIPFILE_OPT; } else if (!PL_strcasecmp(buf, "outfile")) { type = OUTFILE_OPT; } else if (!PL_strcasecmp(buf, "leavearc")) { type = LEAVE_ARC_OPT; } else if (!PL_strcasecmp(buf, "verbosity")) { type = VERBOSITY_OPT; } else if (!PL_strcasecmp(buf, "keysize")) { type = KEYSIZE_OPT; } else if (!PL_strcasecmp(buf, "token")) { type = TOKEN_OPT; } else if (!PL_strcasecmp(buf, "xpi")) { type = XPI_ARC_OPT; } else { PR_fprintf(errorFD, "warning: unknown attribute \"%s\" in command file, line %d.\n", buf, linenum); warningCount++; type = UNKNOWN_OPT; } /* Process the option, whatever it is */ if (type != UNKNOWN_OPT) { if (ProcessOneOpt(type, equals) == -1) { goto finish; } } } retval = 0; finish: PR_Close(fd); return retval; }
int write_stats_dump(PRFileDesc *fd, StatsHeaderNode *hdr) { int i = 0; StatsManager::lockStatsData(); const StatsHeader *hdrStats = &hdr->hdrStats; // Version PR_fprintf(fd, "\n%s\n", hdrStats->versionServer); // Uptime char buffer[25]; PRExplodedTime tm; PR_ExplodeTime(hdrStats->timeStarted, PR_LocalTimeParameters, &tm); PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm); PR_fprintf(fd, "\nServer started %s\n", buffer); { StatsProcessNode *process = hdr->process; while (process) { const StatsProcessSlot *procStats = &process->procStats; PR_ExplodeTime(procStats->timeStarted, PR_LocalTimeParameters, &tm); PR_FormatTimeUSEnglish(buffer, sizeof(buffer), "%c", &tm); PR_fprintf(fd, "Process %d started %s\n", procStats->pid, buffer); process = process->next; } } // ConnectionQueue { StatsConnectionQueueSlot connqueues; memset(&connqueues, 0, sizeof(connqueues)); // Accumulate connection queue buckets for every process StatsProcessNode *process = hdr->process; while (process) { StatsConnectionQueueNode *connQueueNode = process->connQueue; while (connQueueNode) { const StatsConnectionQueueSlot *connqueue = &connQueueNode->connQueueStats; connqueues.countQueued += connqueue->countQueued; connqueues.peakQueued += connqueue->peakQueued; connqueues.maxQueued += connqueue->maxQueued; connqueues.countOverflows += connqueue->countOverflows; connqueues.countTotalQueued += connqueue->countTotalQueued; connqueues.ticksTotalQueued += connqueue->ticksTotalQueued; connqueues.countTotalConnections += connqueue->countTotalConnections; connqueues.countQueued1MinuteAverage += connqueue->countQueued1MinuteAverage; connqueues.countQueued5MinuteAverage += connqueue->countQueued5MinuteAverage; connqueues.countQueued15MinuteAverage += connqueue->countQueued15MinuteAverage; connQueueNode = connQueueNode->next; } process = process->next; } PRFloat64 count = (PRInt64)connqueues.countTotalQueued; PRFloat64 ticks = (PRInt64)connqueues.ticksTotalQueued; if (count < 1.0) count = 1.0; PR_fprintf(fd, "\nConnectionQueue:\n" "-----------------------------------------\n" "Current/Peak/Limit Queue Length %d/%d/%d\n" "Total Connections Queued %llu\n" "Average Queue Length (1, 5, 15 minutes) %4.2f, %4.2f, %4.2f\n" "Average Queueing Delay %.2f milliseconds\n", connqueues.countQueued, connqueues.peakQueued, connqueues.maxQueued, connqueues.countTotalQueued, connqueues.countQueued1MinuteAverage, connqueues.countQueued5MinuteAverage, connqueues.countQueued15MinuteAverage, ticks / count / hdrStats->ticksPerSecond * 1000.0); } // Listen sockets { StatsProcessNode *process = hdr->process; StatsListenNode *lsNode = (process) ? process->ls : 0; while (lsNode) { StatsListenSlot *ls = &lsNode->lsStats; PRNetAddr addr; memcpy(&addr, &ls->address, sizeof(ls->address)); char szAddress[512]; memset(szAddress, 0, sizeof(szAddress)); net_addr_to_string(&addr, szAddress, sizeof(szAddress)-1); PR_fprintf(fd, "\nListenSocket %s:\n" "------------------------\n" "Address %s://%s:%hu\n" "Acceptor Threads %d\n" "Default Virtual Server %s\n", ls->id, ls->flagSecure ? "https" : "http", szAddress, PR_ntohs(ls->address.inet.port), ls->countAcceptors, ls->defaultVsId ); lsNode = lsNode->next; } } // Keepalive Info { StatsKeepaliveBucket keepalives; memset(&keepalives, 0, sizeof(keepalives)); // Accumulate keepalive buckets for every process StatsProcessNode *process = hdr->process; while (process) { StatsKeepaliveBucket *procKeepAlive = NULL; procKeepAlive = &process->procStats.keepAliveBucket; StatsManagerUtil::accumulateKeepAlive(&keepalives, procKeepAlive); process = process->next; } PR_fprintf(fd, "\nKeepAliveInfo:\n" "--------------------\n" "KeepAliveCount %lu/%lu\n" "KeepAliveHits %llu\n" "KeepAliveFlushes %llu\n" "KeepAliveRefusals %llu\n" "KeepAliveTimeouts %llu\n" "KeepAliveTimeout %lu seconds\n", keepalives.countConnections, keepalives.maxConnections, keepalives.countHits, keepalives.countFlushes, keepalives.countRefusals, keepalives.countTimeouts, keepalives.secondsTimeout); } // Session Creation Info { PRUint32 countThreads = 0; PRUint32 countBusy = 0; PRUint32 countKeepAlive = 0; PRUint32 countKeepAliveThreads = 0; // Count the number of active threads StatsProcessNode *process = hdr->process; while (process) { StatsProcessSlot *procStats = &process->procStats; if (procStats->mode != STATS_PROCESS_EMPTY) { StatsThreadNode *thread = process->thread; while (thread) { const StatsThreadSlot *threadStats = &thread->threadStats; if (threadStats->mode != STATS_THREAD_EMPTY) { countThreads++; if (threadStats->mode == STATS_THREAD_KEEPALIVE) { countKeepAlive++; } else if (threadStats->mode != STATS_THREAD_IDLE) { countBusy++; } } thread = thread->next; } } // Get number of keepalive threads StatsKeepaliveBucket *procKeepAlive = NULL; procKeepAlive = &process->procStats.keepAliveBucket; countKeepAliveThreads += procKeepAlive->numThreads; process = process->next; } PR_fprintf(fd, "\nSessionCreationInfo:\n" "------------------------\n" "Active Sessions %lu\n" "Keep-Alive Sessions %lu\n" "Total Sessions Created %lu/%lu\n", countBusy, countKeepAlive, countThreads, (hdrStats->maxThreads * hdrStats->maxProcs + countKeepAliveThreads)); } // Cache Info { StatsCacheBucket caches; memset(&caches, 0, sizeof(caches)); // Accumulate cache buckets for every process StatsProcessNode *process = hdr->process; while (process) { StatsCacheBucket *procCache = NULL; procCache = &process->procStats.cacheBucket; StatsManagerUtil::accumulateCache(&caches, procCache); process = process->next; } if (caches.flagEnabled) { PR_fprintf(fd, "\nCacheInfo:\n" "-----------------------\n"); PRInt64 fileLookups = caches.countHits + caches.countMisses; PR_fprintf(fd, "File Cache Enabled yes\n" "File Cache Entries %lu/%lu\n" "File Cache Hit Ratio %llu/%lld (%6.2f%%)\n" "Maximum Age %d\n", caches.countEntries, caches.maxEntries, caches.countHits, fileLookups, percent(caches.countHits, fileLookups), caches.secondsMaxAge); PRInt64 accelRequests = caches.countAcceleratableRequests + caches.countUnacceleratableRequests; PRInt64 accelResponses = caches.countAcceleratableResponses + caches.countUnacceleratableResponses; PRInt64 accelLookups = caches.countAcceleratorHits + caches.countAcceleratorMisses; PR_fprintf(fd, "Accelerator Entries %lu/%lu\n" "Acceleratable Requests %llu/%lld (%6.2f%%)\n" "Acceleratable Responses %llu/%lld (%6.2f%%)\n" "Accelerator Hit Ratio %llu/%lld (%6.2f%%)\n", caches.countAcceleratorEntries, caches.maxEntries, caches.countAcceleratableRequests, accelRequests, percent(caches.countAcceleratableRequests, accelRequests), caches.countAcceleratableResponses, accelResponses, percent(caches.countAcceleratableResponses, accelResponses), caches.countAcceleratorHits, accelLookups, percent(caches.countAcceleratorHits, accelLookups)); } else { PR_fprintf(fd, "\nServer cache disabled\n"); } } // Thread pool info { StatsThreadPoolBucket pools[FUNC_MAXPOOLS]; const char *names[FUNC_MAXPOOLS]; memset(pools, 0, sizeof(pools)); memset(names, 0, sizeof(names)); // Accumulate thread pool buckets for every process StatsProcessNode *process = hdr->process; while (process) { StatsThreadPoolNode *pool = process->threadPool; for (i = 0; pool && (i < FUNC_MAXPOOLS); i++) { StatsManagerUtil::accumulateThreadPool(&pools[i], &pool->threadPoolStats); names[i] = STATS_GET_NAME(&pool->threadPoolStats); pool = pool->next; } process = process->next; } int poolFlag = 0; for (i = 0; i < FUNC_MAXPOOLS; i++) { if (names[i]) { if (!poolFlag) { poolFlag = 1; PR_fprintf(fd, "\nNative pools:\n" "----------------------------\n"); } PR_fprintf(fd, "%s:\n" "Idle/Peak/Limit %lu/%lu/%lu\n" "Work Queue Length/Peak/Limit %lu/%lu/%lu\n", names[i], pools[i].countThreadsIdle, pools[i].countThreads, pools[i].maxThreads, pools[i].countQueued, pools[i].peakQueued, pools[i].maxQueued); } } } // DNS info { StatsDnsBucket dnss; memset(&dnss, 0, sizeof(dnss)); // Accumulate DNS buckets for every process StatsProcessNode *process = hdr->process; while (process) { StatsManagerUtil::accumulateDNS(&dnss, &process->procStats.dnsBucket); process = process->next; } if (dnss.flagCacheEnabled) { PRUint32 totalhits = dnss.countCacheMisses + dnss.countCacheHits; float hitratio; if (totalhits > 0.0) hitratio = (float)dnss.countCacheHits / (float)totalhits; else hitratio = 0.0; PR_fprintf(fd, "\nDNSCacheInfo:\n" "------------------\n" "enabled yes\n" "CacheEntries %lu/%lu\n" "HitRatio %lu/%lu (%6.2f%%)\n", dnss.countCacheEntries, dnss.maxCacheEntries, dnss.countCacheHits, totalhits, hitratio * 100.0); } else { PR_fprintf(fd, "\nServer DNS cache disabled\n"); } if (dnss.flagAsyncEnabled) { PR_fprintf(fd, "\nAsyncDNS Data:\n" "------------------\n" "enabled yes\n" "NameLookups %lu\n" "AddrLookups %lu\n" "LookupsInProgress %lu\n", dnss.countAsyncNameLookups, dnss.countAsyncAddrLookups, dnss.countAsyncLookupsInProgress); } else { PR_fprintf(fd, "\nAsync DNS disabled\n"); } } // NSAPI Profile Info if (hdrStats->maxProfileBuckets) { int i; StatsProfileBucket *profiles = new StatsProfileBucket[hdrStats->maxProfileBuckets]; const char **names = new const char*[hdrStats->maxProfileBuckets]; const char **descs = new const char*[hdrStats->maxProfileBuckets]; memset(profiles, 0, sizeof(profiles[0]) * hdrStats->maxProfileBuckets); memset(names, 0, sizeof(names[0]) * hdrStats->maxProfileBuckets); memset(descs, 0, sizeof(descs[0]) * hdrStats->maxProfileBuckets); // Accumulate profiles for every thread StatsProcessNode *process = hdr->process; while (process) { StatsThreadNode *thread = process->thread; while (thread) { StatsProfileNode *profile = thread->profile; for (i = 0; i < hdrStats->maxProfileBuckets; i++) { StatsManagerUtil::accumulateProfile(&profiles[i], &profile->profileStats); names[i] = STATS_GET_NAME(&profile->profileStats); descs[i] = STATS_GET_DESCRIPTION(&profile->profileStats); profile = profile->next; } thread = thread->next; } process = process->next; } PRInt64 tr = profiles[STATS_PROFILE_ALL].countRequests; PRInt64 tc = profiles[STATS_PROFILE_ALL].countCalls; float td = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksDispatch; float tf = (float)(PRInt64)profiles[STATS_PROFILE_ALL].ticksFunction; td /= hdrStats->ticksPerSecond; tf /= hdrStats->ticksPerSecond; float tt = td + tf; PR_fprintf(fd, "\nPerformance Counters:\n" "------------------------------------------------\n" " Average Total Percent\n\n" "Total number of requests: %10llu\n" "Request processing time: %7.4f %12.4f\n", tr, (tr > 0) ? (tt / (float)tr) : 0, tt); for (i = hdrStats->maxProfileBuckets-1; i >= STATS_PROFILE_DEFAULT; i--) { PRInt64 r = profiles[i].countRequests; PRInt64 c = profiles[i].countCalls; const char *name = names[i]; // Don't display cache-bucket if it's empty. This is a predefined // bucket that stored NSAPI accelerator cache statistics in // previous versions of the server. if (!c && i == STATS_PROFILE_CACHE && !strcmp(name, "cache-bucket")) { continue; } float d = (float)(PRInt64)profiles[i].ticksDispatch; float f = (float)(PRInt64)profiles[i].ticksFunction; d /= hdrStats->ticksPerSecond; f /= hdrStats->ticksPerSecond; float t = d + f; PR_fprintf(fd, "\n%s (%s)\n" "Number of Requests: %12llu (%6.2f%%)\n" "Number of Invocations: %12llu (%6.2f%%)\n" "Latency: %7.4f %12.4f (%6.2f%%)\n" "Function Processing Time: %7.4f %12.4f (%6.2f%%)\n" "Total Response Time: %7.4f %12.4f (%6.2f%%)\n", name, SAFESTRING(descs[i]), r, (tr > 0) ? (100.0 * r / (PRFloat64) tr) : 0, c, (tc > 0) ? (100.0 * c / (PRFloat64) tc) : 0, (r > 0)? (d / r): 0, d, (tt > 0)? (100 * d / tt): 0, (r > 0)? (f / r): 0, f, (tt > 0)? (100 * f / tt): 0, (r > 0)? (t / r): 0, t, (tt > 0)? (100 * t / tt): 0); } delete[] profiles; delete[] names; delete[] descs; } else { PR_fprintf(fd, "\nPerformance Statistics disabled\n"); } // Session info { StatsProcessNode *process; int x; int y; // Count the number of rows in our session table int nr = 0; for (process = hdr->process; process; process = process->next) { StatsThreadNode *thread; for (thread = process->thread; thread; thread = thread->next) nr++; } SessionRow *rows = new SessionRow[nr]; PRTime now = PR_Now(); // Collect stats from each session y = 0; for (process = hdr->process; process; process = process->next) { StatsThreadNode *thread; for (thread = process->thread; thread; thread = thread->next) { thread->lock(); PRUint32 mode = thread->threadStats.mode; if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE && mode != STATS_THREAD_KEEPALIVE) { rows[y].columns[SESSION_COLUMN_PROCESS].printf("%u", process->procStats.pid); rows[y].columns[SESSION_COLUMN_STATUS] = StatsManager::getMode(&thread->threadStats); char addr[NET_ADDR_STRING_SIZE]; net_addr_to_string(&thread->threadStats.addressClient, addr, sizeof(addr)); rows[y].columns[SESSION_COLUMN_CLIENT] = addr; rows[y].timeRequestStarted = thread->threadStats.timeRequestStarted; if (rows[y].timeRequestStarted != 0) { PRTime microseconds = now - rows[y].timeRequestStarted; int seconds = (microseconds + PR_USEC_PER_SEC/2) / PR_USEC_PER_SEC; rows[y].columns[SESSION_COLUMN_AGE].printf("%d", seconds); } rows[y].columns[SESSION_COLUMN_VS] = thread->threadStats.vsId; rows[y].columns[SESSION_COLUMN_METHOD] = thread->threadStats.requestBucket.method; rows[y].columns[SESSION_COLUMN_URI] = thread->threadStats.requestBucket.uri; rows[y].columns[SESSION_COLUMN_FUNCTION] = STATS_GET_FUNCTION_NAME(&thread->threadStats); y++; } thread->unlock(); } } // We'll only display stats for active sessions PR_ASSERT(y <= nr); nr = y; // Each column is at least as wide as its label int widths[SESSION_COLUMN_COUNT]; for (x = 0; x < SESSION_COLUMN_COUNT; x++) widths[x] = session_column_labels[x].length(); // Ensure each column is wide enough to fit its largest value for (y = 0; y < nr; y++) { for (x = 0; x < SESSION_COLUMN_COUNT; x++) { if (widths[x] < rows[y].columns[x].length()) widths[x] = rows[y].columns[x].length(); } } // Leave at least 2 spaces between columns for (x = 0; x < SESSION_COLUMN_COUNT - 1; x++) widths[x] += 2; // Calculate total line width and individual column offsets int width = 0; int offsets[SESSION_COLUMN_COUNT]; for (x = 0 ; x < SESSION_COLUMN_COUNT; x++) { offsets[x] = width; width += widths[x]; } char *line = (char *) malloc(width + sizeof('\n')); // Output table heading and column labels PR_fprintf(fd, "\nSessions:\n"); memset(line, '-', width); line[width] = '\n'; PR_Write(fd, line, width + sizeof('\n')); PR_Write(fd, line, format_session(line, offsets, session_column_labels)); PR_Write(fd, "\n", 1); // Sort rows by age const SessionRow **sorted = new const SessionRow *[nr]; for (y = 0; y < nr; y++) sorted[y] = &rows[y]; qsort(sorted, nr, sizeof(sorted[0]), &session_cmp); // Output individual rows for (y = 0; y < nr; y++) PR_Write(fd, line, format_session(line, offsets, sorted[y]->columns)); delete [] sorted; free(line); delete [] rows; } StatsManager::unlockStatsData(); return REQ_PROCEED; }