Index: kio/kio/kprotocolmanager.h
===================================================================
--- kio/kio/kprotocolmanager.h	(revision 768586)
+++ kio/kio/kprotocolmanager.h	(working copy)
@@ -64,19 +64,20 @@
 
 
   /**
-   * Returns the default user-agent string.
+   * Returns the default user-agent string used for web browsing.
    *
    * @return the default user-agent string
    */
   static QString defaultUserAgent();
 
   /**
-   * Returns the default user-agent value.
+   * Returns the default user-agent value used for web browsing, for example
+   * "Mozilla/5.0 (compatible; Konqueror/4.0; Linux; X11; i686; en_US) KHTML/4.0.1 (like Gecko)"
    *
    * @param keys can be any of the following:
    * @li 'o'	Show OS
    * @li 'v'	Show OS Version
-   * @li 'p'	Show platform
+   * @li 'p'	Show platform (only for X11)
    * @li 'm'	Show machine architecture
    * @li 'l'	Show language
    * @return the default user-agent value with the given @p keys
@@ -84,7 +85,22 @@
   static QString defaultUserAgent(const QString &keys);
 
   /**
-   * Returns the userAgent string configured for the
+   * Returns the application's user-agent string.
+   * Example string is "KMail/1.9.50 (Windows/6.0; KDE/3.97.1; i686; svn-762186; 2008-01-15)",
+   * where "KMail" is the @p appName parameter, "1.9.50" is the @p appVersion parameter,
+   * "Windows/6.0; KDE/3.97.1; i686" part is added automatically and "svn-762186; 2008-01-15"
+   * is provided by @p extraInfo list.
+   *
+   * @param appName name of the application
+   * @param appVersion name of the application
+   * @param extraInfo a list of elements that will be appended to the string as extra information
+   * @return the application's user-agent string
+   */
+  static QString userAgentForApplication( const QString &appName, const QString& appVersion, 
+    const QStringList& extraInfo = QStringList() );
+
+  /**
+   * Returns the user-agent string configured for the
    * specified host.
    *
    * If hostname is not found or is empty (i.e. "" or
@@ -92,11 +108,24 @@
    * user agent.
    *
    * @param hostname name of the host
-   * @return specified userAgent string
+   * @return specified user-agent string
    */
   static QString userAgentForHost( const QString &hostname );
 
+  /*
+   * Returns system name, version and machine type, for example "Windows", "5.1", "i686".
+   * This information can be used for constructing custom user-agent strings.
+   *
+   * @param systemName system name
+   * @param systemVersion system version
+   * @param machine machine type
 
+   * @return true if system name, version and machine type has been provided
+   */
+  static bool getSystemNameVersionAndMachine(
+    QString& systemName, QString& systemVersion, QString& machine );
+
+
 /*=========================== TIMEOUT CONFIG ================================*/
 
 
Index: kio/kio/kprotocolmanager.cpp
===================================================================
--- kio/kio/kprotocolmanager.cpp	(revision 768586)
+++ kio/kio/kprotocolmanager.cpp	(working copy)
@@ -21,6 +21,7 @@
 #include "kprotocolmanager.h"
 
 #include <string.h>
+#include <unistd.h>
 #include <sys/utsname.h>
 #include <QtCore/QCoreApplication>
 #include <QtDBus/QtDBus>
@@ -70,6 +71,7 @@
     qRemovePostRoutine(kProtocolManagerPrivate.destroy);
 }
 
+// user agent, e.g. KMail/1.9.50 (Windows/5.0; KDE/3.97.1; i686; svn-762186; 2008-01-15)
 
 // DEFAULT USERAGENT STRING
 #define CFG_DEFAULT_UAGENT(X) \
@@ -441,23 +443,24 @@
   if (d->modifiers == modifiers)
      return d->useragent;
 
-  QString supp;
-  struct utsname nam;
-  if( uname(&nam) >= 0 )
+  QString systemName, systemVersion, machine, supp;
+  if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
   {
     if( modifiers.contains('o') )
     {
-      supp += QString("; %1").arg(nam.sysname);
+      supp += QString("; %1").arg(systemName);
       if ( modifiers.contains('v') )
-        supp += QString(" %1").arg(nam.release);
+        supp += QString(" %1").arg(systemVersion);
     }
+#ifdef Q_WS_X11
     if( modifiers.contains('p') )
     {
-      supp += QLatin1String("; X11");  // TODO: determine this valye instead of hardcoding...
+      supp += QLatin1String("; X11");
     }
+#endif
     if( modifiers.contains('m') )
     {
-      supp += QString("; %1").arg(nam.machine);
+      supp += QString("; %1").arg(machine);
     }
     if( modifiers.contains('l') )
     {
@@ -469,6 +472,51 @@
   return d->useragent;
 }
 
+QString KProtocolManager::userAgentForApplication( const QString &appName, const QString& appVersion, 
+  const QStringList& extraInfo )
+{
+  QString systemName, systemVersion, machine;
+  QStringList info;
+  if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
+    info += QString::fromLatin1("%1/%2").arg(systemName).arg(systemVersion);
+  info += QString::fromLatin1("KDE/%1.%2.%3").arg(KDE_VERSION_MAJOR)
+    .arg(KDE_VERSION_MINOR).arg(KDE_VERSION_RELEASE);
+  if (!machine.isEmpty())
+    info += machine;
+  info += extraInfo;
+  return QString::fromLatin1("%1/%2 (%3)").arg(appName).arg(appVersion).arg(info.join("; "));
+}
+
+bool KProtocolManager::getSystemNameVersionAndMachine(
+  QString& systemName, QString& systemVersion, QString& machine )
+{
+  struct utsname unameBuf;
+  if ( 0 != uname( &unameBuf ) )
+    return false;
+#ifdef Q_WS_WIN
+  // we do not use unameBuf.sysname information constructed in kdewin32
+  // because we want to get separate name and version
+  systemName = QLatin1String( "Windows" );
+  OSVERSIONINFOEX versioninfo;
+  ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
+  // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO
+  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  bool ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
+  if ( !ok ) {
+    versioninfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+    ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
+  }
+  if ( ok )
+    systemVersion = QString::fromLatin1("%1.%2")
+      .arg(versioninfo.dwMajorVersion).arg(versioninfo.dwMinorVersion);
+#else
+  systemName = unameBuf.sysname;
+  systemVersion = unameBuf.release;
+#endif
+  machine = unameBuf.machine;
+  return true;
+}
+
 QString KProtocolManager::acceptLanguagesHeader()
 {
   static const QString &english = KGlobal::staticQString("en");
