예제 #1
0
static void
error(Pk11Install_Error errcode, ...)
#endif
{

    va_list ap;
    char *errstr;
    Pk11Install_ErrorHandler handler;

    if (!errorHandlerLock) {
        errorHandlerLock = PR_NewLock();
    }

    PR_Lock(errorHandlerLock);

    handler = errorHandler;

    PR_Unlock(errorHandlerLock);

    if (handler) {
#ifdef OSF1
        va_start(ap);
        errstr = PR_vsmprintf(errorString[va_arg(ap, Pk11Install_Error)], ap);
#else
        va_start(ap, errcode);
        errstr = PR_vsmprintf(errorString[errcode], ap);
#endif
        handler(errstr);
        PR_smprintf_free(errstr);
        va_end(ap);
    }
}
예제 #2
0
  void Print(const char* aName, LogLevel aLevel, const char* aFmt, va_list aArgs)
  {
    const size_t kBuffSize = 1024;
    char buff[kBuffSize];

    char* buffToWrite = buff;

    // For backwards compat we need to use the NSPR format string versions
    // of sprintf and friends and then hand off to printf.
    va_list argsCopy;
    va_copy(argsCopy, aArgs);
    size_t charsWritten = PR_vsnprintf(buff, kBuffSize, aFmt, argsCopy);
    va_end(argsCopy);

    if (charsWritten == kBuffSize - 1) {
      // We may have maxed out, allocate a buffer instead.
      buffToWrite = PR_vsmprintf(aFmt, aArgs);
      charsWritten = strlen(buffToWrite);
    }

    // Determine if a newline needs to be appended to the message.
    const char* newline = "";
    if (charsWritten == 0 || buffToWrite[charsWritten - 1] != '\n') {
      newline = "\n";
    }

    FILE* out = mOutFile ? mOutFile : stderr;

    // This differs from the NSPR format in that we do not output the
    // opaque system specific thread pointer (ie pthread_t) cast
    // to a long. The address of the current PR_Thread continues to be
    // prefixed.
    //
    // Additionally we prefix the output with the abbreviated log level
    // and the module name.
    if (!mAddTimestamp) {
      fprintf_stderr(out,
                     "[%p]: %s/%s %s%s",
                     PR_GetCurrentThread(), ToLogStr(aLevel),
                     aName, buffToWrite, newline);
    } else {
      PRExplodedTime now;
      PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
      fprintf_stderr(
          out,
          "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - [%p]: %s/%s %s%s",
          now.tm_year, now.tm_month + 1, now.tm_mday,
          now.tm_hour, now.tm_min, now.tm_sec, now.tm_usec,
          PR_GetCurrentThread(), ToLogStr(aLevel),
          aName, buffToWrite, newline);
    }

    if (mIsSync) {
      fflush(out);
    }

    if (buffToWrite != buff) {
      PR_smprintf_free(buffToWrite);
    }
  }
예제 #3
0
void
js_ReportErrorVA(JSContext *cx, const char *format, va_list ap)
{
    JSStackFrame *fp;
    JSErrorReport report, *reportp;
    char *last;

    fp = cx->fp;
    if (fp && fp->script && fp->pc) {
	report.filename = fp->script->filename;
	report.lineno = js_PCToLineNumber(fp->script, fp->pc);
	/* XXX should fetch line somehow */
	report.linebuf = NULL;
	report.tokenptr = NULL;
	reportp = &report;
    } else {
	reportp = NULL;
    }
    last = PR_vsmprintf(format, ap);
    if (!last)
	return;

    js_ReportErrorAgain(cx, last, reportp);
    free(last);
}
void sbDeviceXMLInfo::LogIfFailed(nsresult aRV, const char * aPrintf, ...)
{
  // Do nothing if no failure
  if (NS_SUCCEEDED(aRV)) {
    return;
  }

  // Check logging pref:
  if (!mLogDeviceInfo) {
    return;
  }

  // Resolve the args to a string
  va_list etc;
  va_start(etc, aPrintf);
  char *why =
    PR_vsmprintf(aPrintf ? aPrintf : "while loading device info", etc);
  va_end(etc);

  // Compose the error message
  nsString msg(NS_LITERAL_STRING("sbDeviceXMLInfo "));
  msg.AppendLiteral(
    sbDeviceUtils::GetDeviceIdentifier(mDevice).BeginReading());
  msg.AppendLiteral(":\nERROR [0x");
  msg.AppendInt(aRV, 16);
  msg.AppendLiteral("]\n");
  msg.Append(NS_ConvertUTF8toUTF16(why));
  PR_smprintf_free(why);

  // Log the error message
  sbErrorConsole::Error("sbDeviceXMLInfo", msg);
}
예제 #5
0
/**
 * Output a string to the user.  This method is really only meant to be used to
 * output last-ditch error messages designed for developers NOT END USERS.
 *
 * @param isError
 *        Pass true to indicate severe errors.
 * @param fmt
 *        printf-style format string followed by arguments.
 */
static void Output(PRBool isError, const char *fmt, ... )
{
  va_list ap;
  va_start(ap, fmt);

#if (defined(XP_WIN) && !MOZ_WINCONSOLE) || defined(WINCE)
  char *msg = PR_vsmprintf(fmt, ap);
  if (msg)
  {
    UINT flags = MB_OK;
    if (isError)
      flags |= MB_ICONERROR;
    else
      flags |= MB_ICONINFORMATION;
    
    wchar_t wide_msg[2048];
    MultiByteToWideChar(CP_ACP,
			0,
			msg,
			-1,
			wide_msg,
			sizeof(wide_msg) / sizeof(wchar_t));
    
    MessageBoxW(NULL, wide_msg, L"XULRunner", flags);

    PR_smprintf_free(msg);
  }
#else
  vfprintf(stderr, fmt, ap);
#endif

  va_end(ap);
}
예제 #6
0
void nsTSubstring_CharT::AppendPrintf( const char* format, ...)
  {
    char *buf;
    va_list ap;
    va_start(ap, format);
    buf = PR_vsmprintf(format, ap);
    AppendASCII(buf);
    PR_smprintf_free(buf);
    va_end(ap);
  }
void sbDeviceXMLInfo::LogArgs(const char * aFmt,
                              va_list aArgs)
{
  char *msg = PR_vsmprintf(aFmt, aArgs);
  sbErrorConsole::Message(
                     "sbDeviceXMLInfo %s:\n%s",
                     sbDeviceUtils::GetDeviceIdentifier(mDevice).BeginReading(),
                     msg);
  PR_smprintf_free(msg);
}
예제 #8
0
void log_print(const PRLogModuleInfo* aModule,
               LogLevel aLevel,
               const char* aFmt, ...)
{
  va_list ap;
  va_start(ap, aFmt);
  char* buff = PR_vsmprintf(aFmt, ap);
  PR_LogPrint("%s", buff);
  PR_smprintf_free(buff);
  va_end(ap);
}
예제 #9
0
// log a message to remote server with a user token id given 
// for the remote server to fill in with user token details.
am_status_t 
Log::rlog(ModuleId module, int remote_log_level, 
	  const char *user_sso_token, const char *format, ...)
    throw()
{
    am_status_t status = AM_SUCCESS;
    char *logMsg = NULL;
    std::string logMessage;
    bool cookieEncoded = false;

    if (rmtLogSvc == NULL || !remoteInitialized) { 
	status = AM_SERVICE_NOT_INITIALIZED;
    }
    else {
	std::va_list args;
	va_start(args, format);
	logMsg = PR_vsmprintf(format, args);
	logMessage = logMsg;
	if (logMsg != NULL) {

            if (logMsg[0] == '\0') {
                Log::log(Log::ALL_MODULES, Log::LOG_WARNING,
                    "Log Record Message is empty");
                return status;
            }

	    try {
		LogRecord logRecord(
			    static_cast<LogRecord::Level>(remote_log_level), 
			    logMessage);
	        std::string userSSOToken = user_sso_token;
		cookieEncoded = userSSOToken.find('%') != std::string::npos;
	        if (cookieEncoded) {
		    userSSOToken = Http::decode(std::string(user_sso_token));
	        }
		logRecord.populateTokenDetails(userSSOToken);
		status = rmtLogSvc->sendLog("", logRecord, "");	
	    }
	    catch (std::exception& exs) {
		status = AM_FAILURE;
	    }
	    catch (...) {
		status = AM_FAILURE;
	    }
	    PR_smprintf_free(logMsg);
	}
	va_end(args);
    }
    return status;
}
예제 #10
0
/*
 * Log url access audit message. This calls doLocalAuditLog()
 * or doRemoteAuditLog() or both methods based on 
 * log.disposition property value.
 */
am_status_t 
Log::auditLog(const char* auditDisposition,
        bool localAuditLogRotate,
        long localAuditFileSize,
        ModuleId module, 
        int remoteLogLevel, 
        const char *userSSOToken, 
        const char *format, 
        ...)
{
    am_status_t status = AM_SUCCESS;
    char *logMsg = NULL;

    std::va_list args;
    va_start(args, format);
    logMsg = PR_vsmprintf(format, args);
    if(logMsg != NULL) {
        
        if ((strcasecmp(auditDisposition, AUDIT_DISPOSITION_REMOTE) == 0) ||
            (strcasecmp(auditDisposition, AUDIT_DISPOSITION_ALL) == 0)) {
            status = doRemoteAuditLog(module,
                remoteLogLevel,
                userSSOToken,
                logMsg
                );
        }

        if (status != AM_SUCCESS ||
            (strcasecmp(auditDisposition, AUDIT_DISPOSITION_LOCAL) == 0) ||
            (strcasecmp(auditDisposition, AUDIT_DISPOSITION_ALL) == 0)) {
            try {
                doLocalAuditLog(module,
                    Log::LOG_INFO,
                    logMsg,
                    localAuditLogRotate,
                    localAuditFileSize);
            } catch(...) {
                status = AM_FAILURE;    
            }
        }
        PR_smprintf_free(logMsg);
    }
    if (status != AM_SUCCESS) {
        Log::log(Log::ALL_MODULES, Log::LOG_ERROR,
                "Log::auditLog(): Both local and remote audit logging failed.");
    }
        
    return status;
}
예제 #11
0
PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap)
{
    /* XXX this could be better */
    PRUint32 rv, len;
    char* msg = PR_vsmprintf(fmt, ap);
    len = strlen(msg);
#ifdef XP_OS2
    /*
     * OS/2 really needs a \r for every \n.
     * In the future we should try to use scatter-gather instead of a
     * succession of PR_Write.
     */
    if (isatty(PR_FileDesc2NativeHandle(fd))) {
        PRUint32 last = 0, idx;
        PRInt32 tmp;
        rv = 0;
        for (idx = 0; idx < len+1; idx++) {
            if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) {
                tmp = PR_Write(fd, msg + last, idx - last);
                if (tmp >= 0) {
                    rv += tmp;
                }
                last = idx;
            }
            /*
             * if current character is \n, and
             * previous character isn't \r, and
             * next character isn't \r
             */
            if (('\n' == msg[idx]) &&
                ((0 == idx) || ('\r' != msg[idx-1])) &&
                ('\r' != msg[idx+1])) {
                /* add extra \r */
                tmp = PR_Write(fd, "\r", 1);
                if (tmp >= 0) {
                    rv += tmp;
                }
            }
        }
    } else {
        rv = PR_Write(fd, msg, len);
    }
#else
    rv = PR_Write(fd, msg, len);
#endif
    PR_DELETE(msg);
    return rv;
}
예제 #12
0
파일: ch_malloc.c 프로젝트: leto/389-ds
char *
slapi_ch_smprintf(const char *fmt, ...)
{
	char *p = NULL;
	va_list ap;

	if (NULL == fmt) {
		return NULL;
	}

	va_start(ap, fmt);
	p = PR_vsmprintf(fmt, ap);
	va_end(ap);

	return p;
}
예제 #13
0
void
nsChromeRegistry::LogMessage(const char* aMsg, ...)
{
    nsCOMPtr<nsIConsoleService> console
    (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
    if (!console)
        return;

    va_list args;
    va_start(args, aMsg);
    char* formatted = PR_vsmprintf(aMsg, args);
    va_end(args);
    if (!formatted)
        return;

    console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted).get());
    PR_smprintf_free(formatted);
}
예제 #14
0
파일: mempool.c 프로젝트: Firstyear/ds
/*
  This implementation is the same as PR_smprintf.  
  The above comment does not apply to this function for now.
  see [150809] for more details.
  WARNING - with this fix, this means we are now mixing PR_Malloc with
  slapi_ch_free.  Which is ok for now - they both use malloc/free from
  the operating system.  But if this changes in the future, this
  function will have to change as well.
*/
char *
slapi_ch_smprintf(const char *fmt, ...)
{
	char *p = NULL, *q = NULL;
	va_list ap;

	if (NULL == fmt) {
		return NULL;
	}

	va_start(ap, fmt);
	p = PR_vsmprintf(fmt, ap);
	va_end(ap);

	q = slapi_ch_strdup (p); 	/* ugly ...; hope there's any better way */
	free(p);

	return q;
}
예제 #15
0
/**
 * Output a string to the user.  This method is really only meant to be used to
 * output last-ditch error messages designed for developers NOT END USERS.
 *
 * @param isError
 *        Pass true to indicate severe errors.
 * @param fmt
 *        printf-style format string followed by arguments.
 */
static void Output(PRBool isError, const char *fmt, ... )
{
  va_list ap;
  va_start(ap, fmt);

#if defined(XP_WIN) && !MOZ_WINCONSOLE
  char *msg = PR_vsmprintf(fmt, ap);
  if (msg)
  {
    UINT flags = MB_OK;
    if (isError)
      flags |= MB_ICONERROR;
    else 
      flags |= MB_ICONINFORMATION;
    MessageBox(NULL, msg, "XULRunner", flags);
    PR_smprintf_free(msg);
  }
#else
  vfprintf(stderr, fmt, ap);
#endif

  va_end(ap);
}
Result Context::createErrorResultv(const char *fmt, va_list args)
{
    if (fmt == NULL)
        return Result::out_of_memory;

    char *s = PR_vsmprintf(fmt, args);
    if (s == NULL)
        return Result::out_of_memory;

    int len = strlen(s);

    char *p = (char *) pool_malloc(pool, len + 1);
    if (p == NULL) {
        PR_Free(s);
        return Result::out_of_memory;
    }

    memcpy(p, s, len);
    p[len] = '\0';

    PR_Free(s);

    return Result(RESULT_ERROR, PR_FALSE, -1, pool, p, len);
}
예제 #17
0
void
nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
                                        const char* aMsg, ...)
{
    nsresult rv;

    nsCOMPtr<nsIConsoleService> console
    (do_GetService(NS_CONSOLESERVICE_CONTRACTID));

    nsCOMPtr<nsIScriptError> error
    (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
    if (!console || !error)
        return;

    va_list args;
    va_start(args, aMsg);
    char* formatted = PR_vsmprintf(aMsg, args);
    va_end(args);
    if (!formatted)
        return;

    nsCString spec;
    if (aURL)
        aURL->GetSpec(spec);

    rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
                     NS_ConvertUTF8toUTF16(spec).get(),
                     nsnull,
                     aLineNumber, 0, flags, "chrome registration");
    PR_smprintf_free(formatted);

    if (NS_FAILED(rv))
        return;

    console->LogMessage(error);
}
예제 #18
0
/*
 * This function takes an error code and associated error data
 * and creates a string containing a textual description of
 * what the error is and why it happened.
 *
 * The returned string is allocated and thus should be freed
 * once it has been used.
 */
PUBLIC char *
NET_ExplainErrorDetails (int code, ...)
{
  va_list args;
  char *msg = 0;
  int sub_error;

  va_start (args, code);

  if (IS_SSL_ERROR(code) || IS_SEC_ERROR(code)) {
	  const char *s = XP_GetString(code);
	  msg = (s ? XP_STRDUP(s) : 0);
  }

  if (!msg)
    switch(code) {
	case MK_INTERRUPTED:
	case MK_USE_FTP_INSTEAD:
	case MK_USE_COPY_FROM_CACHE:
	case MK_MAILTO_NOT_READY:
	case MK_UNABLE_TO_LOGIN:
	case MK_UNABLE_TO_CONVERT:
	case MK_IMAGE_LOSSAGE:  /* image library generic error */
	case MK_ERROR_SENDING_DATA_COMMAND:
	case MK_OFFLINE:
		msg = NULL;
		break;

	case MK_REDIRECT_ATTEMPT_NOT_ALLOWED:
	case MK_SERVER_TIMEOUT:
	case MK_CONNECTION_TIMED_OUT:
	case MK_OUT_OF_MEMORY:
	case MK_TIMEBOMB_URL_PROHIBIT:
	case MK_TIMEBOMB_MESSAGE:
	case MK_RELATIVE_TIMEBOMB_MESSAGE:
	case MK_NO_WAIS_PROXY:
	case MK_CREATING_NEWSRC_FILE:
	case MK_NNTP_SERVER_NOT_CONFIGURED:
	case MK_NNTP_NEWSGROUP_SCAN_ERROR:
	case MK_ZERO_LENGTH_FILE:
	case MK_BAD_CONNECT:
	case MK_UNABLE_TO_USE_PASV_FTP:
	case MK_UNABLE_TO_CHANGE_FTP_MODE:
	case MK_UNABLE_TO_FTP_CWD:
	case MK_UNABLE_TO_SEND_PORT_COMMAND:
	case MK_UNABLE_TO_ACCEPT_SOCKET:
	case MK_UNABLE_TO_CONNECT2:
	case MK_BAD_NNTP_CONNECTION:
	case MK_NNTP_SERVER_ERROR:
	case MK_SERVER_DISCONNECTED:
	case MK_NEWS_ITEM_UNAVAILABLE:
	case MK_UNABLE_TO_OPEN_NEWSRC:
	case MK_COULD_NOT_LOGIN_TO_SMTP_SERVER:
	case MK_MSG_NO_SMTP_HOST:
	case MK_COULD_NOT_GET_USERS_MAIL_ADDRESS:
	case MK_UNABLE_TO_CONNECT_TO_PROXY:
	case MK_UNABLE_TO_LOCATE_PROXY:
	case MK_DISK_FULL:
	case MK_PRINT_LOSSAGE:
	case MK_SECURE_NEWS_PROXY_ERROR:
	case MK_SIGNATURE_TOO_LONG:
	case MK_SIGNATURE_TOO_WIDE:
	case MK_POP3_SERVER_ERROR:
	case MK_POP3_USERNAME_UNDEFINED:
	case MK_POP3_PASSWORD_UNDEFINED:
	case MK_POP3_USERNAME_FAILURE:
	case MK_POP3_PASSWORD_FAILURE:
	case MK_POP3_NO_MESSAGES:
	case MK_POP3_LIST_FAILURE:
	case MK_POP3_LAST_FAILURE:
	case MK_POP3_RETR_FAILURE:
	case MK_POP3_DELE_FAILURE:
	case MK_POP3_OUT_OF_DISK_SPACE:
	case MK_POP3_MESSAGE_WRITE_ERROR:
	case MK_MIME_NO_SENDER:
	case MK_MIME_NO_RECIPIENTS:
	case MK_MIME_NO_SUBJECT:
	case MK_MIME_ERROR_WRITING_FILE:
	case MK_MIME_MULTIPART_BLURB:
	case MK_MSG_CANT_COPY_TO_SAME_FOLDER:
	case MK_MSG_CANT_COPY_TO_QUEUE_FOLDER:
	case MK_MSG_CANT_COPY_TO_QUEUE_FOLDER_OLD:
	case MK_MSG_CANT_COPY_TO_DRAFTS_FOLDER:
	case MK_MSG_CANT_CREATE_FOLDER:
	case MK_MSG_FOLDER_ALREADY_EXISTS:
	case MK_MSG_FOLDER_NOT_EMPTY:
	case MK_MSG_CANT_DELETE_FOLDER:
	case MK_MSG_CANT_CREATE_INBOX:
	case MK_MSG_CANT_CREATE_MAIL_DIR:
	case MK_MSG_NO_POP_HOST:
	case MK_MSG_MESSAGE_CANCELLED:
	case MK_MSG_FOLDER_UNREADABLE:
	case MK_MSG_FOLDER_SUMMARY_UNREADABLE:
	case MK_MSG_TMP_FOLDER_UNWRITABLE:
	case MK_MSG_ID_NOT_IN_FOLDER:
	case MK_MSG_NEWSRC_UNPARSABLE:
	case MK_MSG_NO_RETURN_ADDRESS:
	case MK_MSG_ERROR_WRITING_NEWSRC:
	case MK_MSG_ERROR_WRITING_MAIL_FOLDER:
	case MK_MSG_SEARCH_FAILED:
	case MK_MSG_FOLDER_BUSY:
		msg = XP_STRDUP(XP_GetString(code));
		break;

	case MK_TCP_READ_ERROR:
	case MK_TCP_WRITE_ERROR:
	case MK_UNABLE_TO_CREATE_SOCKET:
	case MK_UNABLE_TO_CONNECT:
	case MK_HTTP_TYPE_CONFLICT:
	case MK_TCP_ERROR:
		sub_error = va_arg(args, int);
		if (IS_SSL_ERROR(sub_error) || IS_SEC_ERROR(sub_error)) {
			/*
			 * For SSL/SEC errors, use the message without a wrapper.
			 */
			msg = XP_STRDUP(XP_GetString(sub_error));
		} else if (code == MK_UNABLE_TO_CONNECT &&
				   (sub_error == XP_ERRNO_EINVAL
					|| sub_error == XP_ERRNO_EADDRINUSE)) {
			/*
			 * With unable-to-connect errors, some errno values/strings
			 * are not more helpful, so just use a plain message for these.
			 */
			msg = XP_STRDUP(XP_GetString(MK_UNABLE_TO_CONNECT2));
		} else {
			msg = PR_smprintf(XP_GetString(code), XP_GetString(sub_error));
		}
		break;

	case MK_MALFORMED_URL_ERROR:
	case MK_COULD_NOT_PUT_FILE:
	case MK_UNABLE_TO_LOCATE_FILE:
	case MK_NNTP_AUTH_FAILED:
	case MK_UNABLE_TO_LOCATE_HOST:
	case MK_UNABLE_TO_LOCATE_SOCKS_HOST:
	case MK_UNABLE_TO_OPEN_FILE:
	case MK_UNABLE_TO_OPEN_TMP_FILE:
	case MK_CONNECTION_REFUSED:
	case MK_NNTP_ERROR_MESSAGE:
	case MK_MSG_COULDNT_OPEN_FCC_FILE:
	case MK_TIMEBOMB_WARNING_MESSAGE:
	case MK_RELATIVE_TIMEBOMB_WARNING_MESSAGE:
	case MK_ERROR_SENDING_FROM_COMMAND:
	case MK_ERROR_SENDING_RCPT_COMMAND:
	case MK_ERROR_SENDING_MESSAGE:
	case MK_SMTP_SERVER_ERROR:
		msg = PR_vsmprintf(XP_GetString(code), args);
		break;

	case -1:
	default:
		msg = PR_smprintf(XP_GetString(MK_COMMUNICATIONS_ERROR), code);
		break;
	}

  va_end (args);

  TRACEMSG(("NET_ExplainErrorDetails generated: %s", msg ? msg : "(none)"));

  return(msg);
}
예제 #19
0
PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
{
    va_list ap;
    char line[LINE_BUF_SIZE];
    char *line_long = NULL;
    PRUint32 nb_tid = 0, nb;
    PRThread *me;
    PRExplodedTime now;

    if (!_pr_initialized) _PR_ImplicitInitialization();

    if (!logFile) {
        return;
    }

    if (outputTimeStamp) {
        PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
        nb_tid = PR_snprintf(line, sizeof(line)-1,
                             "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ",
                             now.tm_year, now.tm_month, now.tm_mday,
                             now.tm_hour, now.tm_min, now.tm_sec,
                             now.tm_usec);
    }

    me = PR_GetCurrentThread();
    nb_tid += PR_snprintf(line+nb_tid, sizeof(line)-nb_tid-1, "%ld[%p]: ",
#if defined(_PR_BTHREADS)
                          me, me);
#else
                          me ? me->id : 0L, me);
#endif

    va_start(ap, fmt);
    nb = nb_tid + PR_vsnprintf(line+nb_tid, sizeof(line)-nb_tid-1, fmt, ap);
    va_end(ap);

    /*
     * Check if we might have run out of buffer space (in case we have a
     * long line), and malloc a buffer just this once.
     */
    if (nb == sizeof(line)-2) {
        va_start(ap, fmt);
        line_long = PR_vsmprintf(fmt, ap);
        va_end(ap);
        /* If this failed, we'll fall back to writing the truncated line. */
    }

    if (line_long) {
        nb = strlen(line_long);
        _PR_LOCK_LOG();
        if (logBuf != 0) {
            _PUT_LOG(logFile, logBuf, logp - logBuf);
            logp = logBuf;
        }
        /*
         * Write out the thread id (with an optional timestamp) and the
         * malloc'ed buffer.
         */
        _PUT_LOG(logFile, line, nb_tid);
        _PUT_LOG(logFile, line_long, nb);
        /* Ensure there is a trailing newline. */
        if (!nb || (line_long[nb-1] != '\n')) {
            char eol[2];
            eol[0] = '\n';
            eol[1] = '\0';
            _PUT_LOG(logFile, eol, 1);
        }
        _PR_UNLOCK_LOG();
        PR_smprintf_free(line_long);
    } else {
        /* Ensure there is a trailing newline. */
        if (nb && (line[nb-1] != '\n')) {
            line[nb++] = '\n';
            line[nb] = '\0';
        }
        _PR_LOCK_LOG();
        if (logBuf == 0) {
            _PUT_LOG(logFile, line, nb);
        } else {
            /* If nb can't fit into logBuf, write out logBuf first. */
            if (logp + nb > logEndp) {
                _PUT_LOG(logFile, logBuf, logp - logBuf);
                logp = logBuf;
            }
            /* nb is guaranteed to fit into logBuf. */
            memcpy(logp, line, nb);
            logp += nb;
        }
        _PR_UNLOCK_LOG();
    }
    PR_LogFlush();
}
예제 #20
0
  void Print(const char* aName, LogLevel aLevel, const char* aFmt, va_list aArgs)
  {
    const size_t kBuffSize = 1024;
    char buff[kBuffSize];

    char* buffToWrite = buff;

    // For backwards compat we need to use the NSPR format string versions
    // of sprintf and friends and then hand off to printf.
    va_list argsCopy;
    va_copy(argsCopy, aArgs);
    size_t charsWritten = PR_vsnprintf(buff, kBuffSize, aFmt, argsCopy);
    va_end(argsCopy);

    if (charsWritten == kBuffSize - 1) {
      // We may have maxed out, allocate a buffer instead.
      buffToWrite = PR_vsmprintf(aFmt, aArgs);
      charsWritten = strlen(buffToWrite);
    }

    // Determine if a newline needs to be appended to the message.
    const char* newline = "";
    if (charsWritten == 0 || buffToWrite[charsWritten - 1] != '\n') {
      newline = "\n";
    }

    FILE* out = stderr;

    // In case we use rotate, this ensures the FILE is kept alive during
    // its use.  Increased before we load mOutFile.
    ++mPrintEntryCount;

    detail::LogFile* outFile = mOutFile;
    if (outFile) {
      out = outFile->File();
    }

    // This differs from the NSPR format in that we do not output the
    // opaque system specific thread pointer (ie pthread_t) cast
    // to a long. The address of the current PR_Thread continues to be
    // prefixed.
    //
    // Additionally we prefix the output with the abbreviated log level
    // and the module name.
    PRThread *currentThread = PR_GetCurrentThread();
    const char *currentThreadName = (mMainThread == currentThread)
      ? "Main Thread"
      : PR_GetThreadName(currentThread);

    char noNameThread[40];
    if (!currentThreadName) {
      SprintfLiteral(noNameThread, "Unnamed thread %p", currentThread);
      currentThreadName = noNameThread;
    }

    if (!mAddTimestamp) {
      fprintf_stderr(out,
                     "[%s]: %s/%s %s%s",
                     currentThreadName, ToLogStr(aLevel),
                     aName, buffToWrite, newline);
    } else {
      PRExplodedTime now;
      PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
      fprintf_stderr(
          out,
          "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - [%s]: %s/%s %s%s",
          now.tm_year, now.tm_month + 1, now.tm_mday,
          now.tm_hour, now.tm_min, now.tm_sec, now.tm_usec,
          currentThreadName, ToLogStr(aLevel),
          aName, buffToWrite, newline);
    }

    if (mIsSync) {
      fflush(out);
    }

    if (buffToWrite != buff) {
      PR_smprintf_free(buffToWrite);
    }

    if (mRotate > 0 && outFile) {
      int32_t fileSize = ftell(out);
      if (fileSize > mRotate) {
        uint32_t fileNum = outFile->Num();

        uint32_t nextFileNum = fileNum + 1;
        if (nextFileNum >= kRotateFilesNumber) {
          nextFileNum = 0;
        }

        // And here is the trick.  The current out-file remembers its order
        // number.  When no other thread shifted the global file number yet,
        // we are the thread to open the next file.
        if (mOutFileNum.compareExchange(fileNum, nextFileNum)) {
          // We can work with mToReleaseFile because we are sure the
          // mPrintEntryCount can't drop to zero now - the condition
          // to actually delete what's stored in that member.
          // And also, no other thread can enter this piece of code
          // because mOutFile is still holding the current file with
          // the non-shifted number.  The compareExchange() above is
          // a no-op for other threads.
          outFile->mNextToRelease = mToReleaseFile;
          mToReleaseFile = outFile;

          mOutFile = OpenFile(false, nextFileNum);
        }
      }
    }

    if (--mPrintEntryCount == 0 && mToReleaseFile) {
      // We were the last Print() entered, if there is a file to release
      // do it now.  exchange() is atomic and makes sure we release the file
      // only once on one thread.
      detail::LogFile* release = mToReleaseFile.exchange(nullptr);
      delete release;
    }
  }
예제 #21
0
// this should not throw exception since it is called often in a 
// catch block to log an error resulting from an exception.
void Log::vlog(ModuleId module, Level level, const char *format,
	       std::va_list args) 
    throw()
{
    if (initialized) {
	if (module >= moduleList->size()) {
	    module = ALL_MODULES;
	}

        char *logMsg = PR_vsmprintf(format, args);
	// call user defined logger if any.
	if (loggerFunc != NULL) {
	    loggerFunc((*moduleList)[module].name.c_str(),  
		       static_cast<am_log_level_t>(static_cast<int>(level)),
		       logMsg);
	}

	// do default log.
	if ((*moduleList)[module].level >= level) {

	    // format: 
	    // year-month-day hour:min:sec.usec level pid:thread module: msg
	    // get level string		
	    std::size_t levelLabelIndex = getLevelString(level);
	    char levelStr[50]; 
	    PRUint32 llen;
	    if (levelLabelIndex < numLabels) {
		llen = PR_snprintf(levelStr, sizeof(levelStr),
				       "%s", levelLabels[levelLabelIndex]);
	    } else {
		llen = PR_snprintf(levelStr, sizeof(levelStr), "%d", level);
	    }

	    if (llen > 0) { 
		// get time.
		PRExplodedTime now;
		PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
    
		// format header and msg.
		PRUint32 len;
		char hdr[100];
		len = PR_snprintf(hdr, sizeof(hdr), 
				  "%d-%02d-%02d %02d:%02d:%02d.%03d"
				  "%8s %u:%p %s: %%s\n",
				  now.tm_year, now.tm_month+1, now.tm_mday,
				  now.tm_hour, now.tm_min, now.tm_sec, 
				  now.tm_usec / 1000,
				  levelStr,
				  getpid(), PR_GetCurrentThread(),
				  (*moduleList)[module].name.c_str());
		if (len > 0) {
                  if (logRotation) {
                    if ((currentLogFileSize + 1000) < maxLogFileSize) {
		       std::fprintf(logFile, hdr, logMsg);
		       std::fflush(logFile);
                    } else {
    		      ScopeLock scopeLock(*lockPtr);
                      currentLogFileSize = ftell(logFile);
                      if ((currentLogFileSize + 1000) > maxLogFileSize) {
                         // Open a new log file
	                 if (!pSetLogFile(logFileName)) {
		                 log(ALL_MODULES, LOG_ERROR,
		                 "Unable to open log file: '%s', errno = %d",
		                 logFileName.c_str(), errno);
	                }
                      }
		      std::fprintf(logFile, hdr, logMsg);
		      std::fflush(logFile);
                    }
                    currentLogFileSize = ftell(logFile);
                  } else {
		      std::fprintf(logFile, hdr, logMsg);
		      std::fflush(logFile);
                  }
		}
	     }
	}

	// Remote Logging starts here.
	if (module == remoteModule) {
	    if (remoteInitialized) {
		bool doLogRemotely = 
		    ((*moduleList)[module].level >= Log::LOG_AUTH_REMOTE) &&
		    ((*moduleList)[module].level & level);

		if (doLogRemotely) {
		    am_status_t status;
		    status = rmtLogSvc->logMessage(logMsg);
		    if(status != AM_SUCCESS) {
			Log::log(Log::ALL_MODULES, Log::LOG_ERROR,
			    "Log::vlog(): Error logging message [%s] "
			    "to remote server. Error: %s.", 
			    logMsg, am_status_to_string(status));
		    }
		}
	    } else {
		Log::log(Log::ALL_MODULES, Log::LOG_ERROR,
		    "Log::vlog(): Remote logging service not initialized. "
		    "Cannot log message to remote server.");
	    }
	}
	PR_smprintf_free(logMsg);
    }
    return;
}