Ticket #5319: mythtv-5319-add_query_timezone_to_protocol-20080927.patch

File mythtv-5319-add_query_timezone_to_protocol-20080927.patch, 11.5 KB (added by sphery <mtdean@…>, 12 years ago)

Updated patch for recent include changes in util.cpp

  • libs/libmyth/util.h

    old new  
    2424
    2525MPUBLIC QDateTime mythCurrentDateTime();
    2626MPUBLIC int calc_utc_offset(void);
     27MPUBLIC QString format_utc_offset(void);
     28MPUBLIC QString getTimeZoneID(void);
    2729
    2830// This is necessary for GCC 3.3, which has llabs(long long)
    2931// but not abs(long long) or std::llabs(long long)
  • libs/libmyth/util.cpp

    old new  
    1010#include <unistd.h>
    1111#include <stdlib.h>
    1212#include <fcntl.h>
     13#include <time.h>
    1314
    1415// System specific C headers
    1516#include "compat.h"
     
    4748#include <QPixmap>
    4849#include <QFont>
    4950#include <QFile>
     51#include <QDir>
     52#include <QFileInfo>
    5053
    5154// Myth headers
    5255#include "mythconfig.h"
     
    8689    return utc_offset;
    8790}
    8891
     92QString format_utc_offset(void)
     93{
     94    char offset[32];
     95    int offset_total_seconds, offset_hours, offset_minutes;
     96    QString offset_string("UNDEF");
     97
     98    offset_total_seconds = calc_utc_offset();
     99
     100    offset_hours = offset_total_seconds / 3600;
     101    offset_minutes = abs((offset_total_seconds % 3600) / 60);
     102
     103    if (sprintf(offset, "%.2i:%.2i", offset_hours, offset_minutes) > 0)
     104        offset_string = offset;
     105
     106    return offset_string;
     107}
     108
     109#ifndef USING_MINGW
     110/* Helper function for getSystemTimeZoneID() that compares the
     111   zoneinfo_file_path (regular) file with files in the zoneinfo_dir_path until
     112   it finds a match.  The matching file's name is used to determine the time
     113   zone ID. */
     114static QString findZoneinfoFile(QString zoneinfo_file_path,
     115                                QString zoneinfo_dir_path)
     116{
     117    QString zone_id("UNDEF");
     118    QDir zoneinfo_dir(zoneinfo_dir_path);
     119    QFileInfoList dirlist = zoneinfo_dir.entryInfoList();
     120    QFileInfo info;
     121    QString basename;
     122    QFile zoneinfo_file(zoneinfo_file_path);
     123    qint64 zoneinfo_file_size = zoneinfo_file.size();
     124
     125    for (QFileInfoList::const_iterator it = dirlist.begin();
     126         it != dirlist.end(); it++)
     127    {
     128        info = *it;
     129         // Skip '.' and '..' and other files starting with "." and
     130         // skip localtime (which is often a link to zoneinfo_file_path)
     131        basename = info.baseName();
     132        if (basename.isEmpty() || (basename == "localtime")) {
     133            continue;
     134        }
     135        if (info.isDir())
     136        {
     137            zone_id = findZoneinfoFile(zoneinfo_file_path,
     138                                       info.absoluteFilePath());
     139            if (zone_id != "UNDEF")
     140                return zone_id;
     141        }
     142        else if (info.isFile() && (info.size() == zoneinfo_file_size) &&
     143                 info.isReadable())
     144        {
     145            // sanity check - zoneinfo files should typically be less than
     146            // about 4kB, but leave room for growth
     147            if (zoneinfo_file_size > 200 * 1024)
     148                continue;
     149            QFile this_file(info.absoluteFilePath());
     150            QByteArray zoneinfo_file_data;
     151            zoneinfo_file_data.resize(zoneinfo_file_size);
     152            QByteArray this_file_data;
     153            this_file_data.resize(zoneinfo_file_size);
     154            if (zoneinfo_file.open(QIODevice::ReadOnly))
     155            {
     156                QDataStream in(&zoneinfo_file);
     157                if (in.readRawData(zoneinfo_file_data.data(),
     158                                   zoneinfo_file_size) != zoneinfo_file_size)
     159                {
     160                    zoneinfo_file.close();
     161                    return zone_id;
     162                }
     163                zoneinfo_file.close();
     164            }
     165            if (this_file.open(QIODevice::ReadOnly))
     166            {
     167                QDataStream in(&this_file);
     168                if (in.readRawData(this_file_data.data(),
     169                                   zoneinfo_file_size) != zoneinfo_file_size)
     170                {
     171                    this_file.close();
     172                    return zone_id;
     173                }
     174                this_file.close();
     175            }
     176            if (zoneinfo_file_data == this_file_data)
     177            {
     178                zone_id = info.absoluteFilePath();
     179                break;
     180            }
     181        }
     182    }
     183    return zone_id;
     184}
     185#endif
     186
     187/* Helper function for getTimeZoneID() that provides an unprocessed time zone
     188   id obtained using system-dependent means of identifying the system's time
     189   zone. */
     190static QString getSystemTimeZoneID(void)
     191{
     192    QString zone_id("UNDEF");
     193#ifndef USING_MINGW
     194    // Try to determine the time zone information by inspecting the system
     195    // configuration
     196    bool found = false;
     197    QString time_zone_file_path("/etc/timezone");
     198    QString clock_file_path("/etc/sysconfig/clock");
     199    QString zoneinfo_file_path("/etc/localtime");
     200    QString zoneinfo_dir_path("/usr/share/zoneinfo");
     201
     202    // First, check time_zone_file_path (used by Debian-based systems)
     203    QFile time_zone_file(time_zone_file_path);
     204    QFileInfo info(time_zone_file);
     205    if (info.exists() && info.isFile() && info.isReadable())
     206    {
     207        if (time_zone_file.open(QIODevice::ReadOnly | QIODevice::Text))
     208        {
     209            QString line;
     210            QTextStream in(&time_zone_file);
     211            while (!in.atEnd())
     212            {
     213                line = in.readLine();
     214                line = line.trimmed();
     215                if (!line.startsWith("#"))
     216                {
     217                    zone_id = line;
     218                    found = true;
     219                    break;
     220                }
     221            }
     222            time_zone_file.close();
     223            if (found)
     224                return zone_id;
     225        }
     226    }
     227
     228    // Next, look for the ZONE entry in clock_file_path (used by Red Hat-based
     229    // systems)
     230    QFile clock_file(clock_file_path);
     231    info.setFile(clock_file);
     232    if (info.exists() && info.isFile() && info.isReadable())
     233    {
     234        if (clock_file.open(QIODevice::ReadOnly | QIODevice::Text))
     235        {
     236            QString line;
     237            QTextStream in(&clock_file);
     238            // Handle whitespace and quotes
     239            QRegExp re("^ZONE\\s*=\\s*(?:'|\")?(.+)$");
     240            re.setPatternSyntax(QRegExp::RegExp2);
     241            while (!in.atEnd())
     242            {
     243                line = in.readLine();
     244                if (re.indexIn(line) != -1)
     245                {
     246                    zone_id = re.cap(1);
     247                    found = true;
     248                    break;
     249                }
     250            }
     251            clock_file.close();
     252            if (found)
     253                return zone_id;
     254        }
     255    }
     256
     257    // Next check zoneinfo_file_path
     258    QFile zoneinfo_file(zoneinfo_file_path);
     259    info.setFile(zoneinfo_file);
     260
     261    if (info.exists() && info.isFile())
     262    {
     263        QString tz;
     264        if (info.isSymLink())
     265        {
     266            // The symlink refers to a file whose name contains the zone ID
     267            tz = info.symLinkTarget();
     268        }
     269        else
     270        {
     271            // The zoneinfo_file is a copy of the file in the
     272            // zoneinfo_dir_path, so search for the same file in
     273            // zoneinfo_dir_path
     274            tz = findZoneinfoFile(zoneinfo_file_path, zoneinfo_dir_path);
     275        }
     276        if (tz != "UNDEF")
     277        {
     278            int pos = 0;
     279            // Get the zone ID from the filename
     280            // Look for the basename of zoneinfo_dir_path in case it's a
     281            // relative link
     282            QString zoneinfo_dirname = zoneinfo_dir_path.section('/', -1);
     283            if ((pos = tz.indexOf(zoneinfo_dirname)) != -1)
     284            {
     285                zone_id = tz.right(tz.size() - (pos + 1) -
     286                                   zoneinfo_dirname.size());
     287            }
     288        }
     289        else
     290        {
     291            // If we still haven't found a time zone, try localtime_r() to at
     292            // least get the zone name/abbreviation (as opposed to the
     293            // identifier for the set of rules governing the zone)
     294            char name[64];
     295            time_t t;
     296            struct tm *result = (struct tm *)malloc(sizeof(*result));
     297
     298            t = time(NULL);
     299            localtime_r(&t, result);
     300
     301            if (result != NULL)
     302            {
     303                if (strftime(name, sizeof(name), "%Z", result) > 0)
     304                    zone_id = name;
     305                free(result);
     306            }
     307        }
     308    }
     309
     310#endif
     311    return zone_id;
     312}
     313
     314/** \fn getTimeZoneID()
     315 *  \brief Returns the zoneinfo time zone ID or as much time zone information
     316 *         as possible
     317 */
     318QString getTimeZoneID(void)
     319{
     320    QString zone_id("UNDEF");
     321#ifndef USING_MINGW
     322    // First, try the TZ environment variable to check for environment-specific
     323    // overrides
     324    QString tz = getenv("TZ");
     325    if (tz.isEmpty())
     326    {
     327        // No TZ, so attempt to determine the system-configured time zone ID
     328        tz = getSystemTimeZoneID();
     329    }
     330
     331    if (!tz.isEmpty())
     332    {
     333        zone_id = tz;
     334        if (zone_id.startsWith("\"") || zone_id.startsWith("'"))
     335                zone_id.remove(0, 1);
     336        if (zone_id.endsWith("\"") || zone_id.endsWith("'"))
     337                zone_id.chop(1);
     338        if (zone_id.startsWith(":"))
     339            zone_id.remove(0, 1);
     340        // the "posix/" subdirectory typically contains the same files as the
     341        // "zoneinfo/" parent directory, but are not typically what are in use
     342        if (zone_id.startsWith("posix/"))
     343            zone_id.remove(0, 6);
     344    }
     345
     346#endif
     347    return zone_id;
     348}
     349
    89350/** \fn encodeLongLong(QStringList&,long long)
    90351 *  \brief Encodes a long for streaming in the MythTV protocol.
    91352 *
  • programs/mythbackend/mainserver.h

    old new  
    136136    void HandleQueryLoad(PlaybackSock *pbs);
    137137    void HandleQueryUptime(PlaybackSock *pbs);
    138138    void HandleQueryMemStats(PlaybackSock *pbs);
     139    void HandleQueryTimeZone(PlaybackSock *pbs);
    139140    void HandleBlockShutdown(bool blockShutdown, PlaybackSock *pbs);
    140141   
    141142    void SendResponse(MythSocket *pbs, QStringList &commands);
  • programs/mythbackend/mainserver.cpp

    old new  
    380380    {
    381381        HandleQueryMemStats(pbs);
    382382    }
     383    else if (command == "QUERY_TIME_ZONE")
     384    {
     385        HandleQueryTimeZone(pbs);
     386    }
    383387    else if (command == "QUERY_CHECKFILE")
    384388    {
    385389        HandleQueryCheckFile(listline, pbs);
     
    23872391
    23882392/**
    23892393 * \addtogroup myth_network_protocol
     2394 * \par        QUERY_TIME_ZONE
     2395 * Returns time zone ID, current offset, current time
     2396 */
     2397void MainServer::HandleQueryTimeZone(PlaybackSock *pbs)
     2398{
     2399    MythSocket *pbssock = pbs->getSocket();
     2400    QStringList strlist;
     2401    strlist << getTimeZoneID() << format_utc_offset()
     2402            << mythCurrentDateTime().toString(Qt::ISODate);
     2403
     2404    SendResponse(pbssock, strlist);
     2405}
     2406
     2407/**
     2408 * \addtogroup myth_network_protocol
    23902409 * \par        QUERY_CHECKFILE \e checkslaves \e programinfo
    23912410 */
    23922411void MainServer::HandleQueryCheckFile(QStringList &slist, PlaybackSock *pbs)