~ubuntu-branches/ubuntu/lucid/mythtv/lucid

« back to all changes in this revision

Viewing changes to libs/libmyth/remoteutil.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2009-10-02 00:23:18 UTC
  • mfrom: (1.1.36 upstream)
  • Revision ID: james.westby@ubuntu.com-20091002002318-5qu2fr0gxl59egft
Tags: 0.22.0~trunk22167-0ubuntu1
* New upstream checkout (r22167).
  - Fixes some segfaults.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include <unistd.h>
2
2
 
 
3
#include <QFileInfo>
3
4
#include <QFile>
 
5
#include <QDir>
4
6
 
5
7
#include "remoteutil.h"
6
8
#include "programinfo.h"
7
9
#include "mythcontext.h"
8
10
#include "decodeencode.h"
 
11
#include "storagegroup.h"
9
12
 
10
13
vector<ProgramInfo *> *RemoteGetRecordedList(bool deltype)
11
14
{
287
290
    return retdatetime;
288
291
}
289
292
 
 
293
/// Download preview & get timestamp if newer than cachefile's
 
294
/// last modified time, otherwise just get the timestamp
 
295
QDateTime RemoteGetPreviewIfModified(
 
296
    const ProgramInfo &pginfo, const QString &cachefile)
 
297
{
 
298
    QString loc_err("RemoteGetPreviewIfModified, Error: ");
 
299
 
 
300
    QDateTime cacheLastModified;
 
301
    QFileInfo cachefileinfo(cachefile);
 
302
    if (cachefileinfo.exists())
 
303
        cacheLastModified = cachefileinfo.lastModified();
 
304
 
 
305
    QStringList strlist("QUERY_PIXMAP_GET_IF_MODIFIED");
 
306
    strlist << ((cacheLastModified.isValid()) ? // unix secs, UTC
 
307
                QString::number(cacheLastModified.toTime_t()) : QString("-1"));
 
308
    strlist << QString::number(200 * 1024); // max size of preview file
 
309
    pginfo.ToStringList(strlist);
 
310
 
 
311
    if (!gContext->SendReceiveStringList(strlist) ||
 
312
        strlist.empty() || strlist[0] == "ERROR")
 
313
    {
 
314
        VERBOSE(VB_IMPORTANT, loc_err +
 
315
                QString("Remote error") +
 
316
                ((strlist.size() >= 2) ?
 
317
                 (QString(":\n\t\t\t") + strlist[1]) : QString("")));
 
318
 
 
319
        return QDateTime();
 
320
    }
 
321
 
 
322
    if (strlist[0] == "WARNING")
 
323
    {
 
324
        VERBOSE(VB_NETWORK, QString("RemoteGetPreviewIfModified, Warning: ") +
 
325
                QString("Remote warning") +
 
326
                ((strlist.size() >= 2) ?
 
327
                 (QString(":\n\t\t\t") + strlist[1]) : QString("")));
 
328
 
 
329
        return QDateTime();
 
330
    }
 
331
 
 
332
    QDateTime retdatetime;
 
333
    qlonglong timet = strlist[0].toLongLong();
 
334
    if (timet >= 0)
 
335
        retdatetime.setTime_t(timet);
 
336
 
 
337
    if (strlist.size() < 4)
 
338
    {
 
339
        return retdatetime;
 
340
    }
 
341
 
 
342
    size_t  length     = strlist[1].toLongLong();
 
343
    quint16 checksum16 = strlist[2].toUInt();
 
344
    QByteArray data = QByteArray::fromBase64(strlist[3].toAscii());
 
345
    if ((size_t) data.size() < length)
 
346
    { // (note data.size() may be up to 3 bytes longer after decoding
 
347
        VERBOSE(VB_IMPORTANT, loc_err +
 
348
                QString("Preview size check failed %1 < %2")
 
349
                .arg(data.size()).arg(length));
 
350
        return QDateTime();
 
351
    }
 
352
 
 
353
    if (checksum16 != qChecksum(data.constData(), data.size()))
 
354
    {
 
355
        VERBOSE(VB_IMPORTANT, loc_err + "Preview checksum failed");
 
356
        return QDateTime();
 
357
    }
 
358
 
 
359
    QString pdir(cachefile.section("/", 0, -2));
 
360
    QDir cfd(pdir);
 
361
    if (!cfd.exists() && !cfd.mkdir(pdir))
 
362
    {
 
363
        VERBOSE(VB_IMPORTANT, loc_err +
 
364
                QString("Unable to create remote cache directory '%1'")
 
365
                .arg(pdir));
 
366
 
 
367
        return QDateTime();
 
368
    }
 
369
 
 
370
    QFile file(cachefile);
 
371
    if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate))
 
372
    {
 
373
        VERBOSE(VB_IMPORTANT, loc_err +
 
374
                QString("Unable to open cached "
 
375
                        "preview file for writing '%1'")
 
376
                .arg(cachefile));
 
377
 
 
378
        return QDateTime();
 
379
    }
 
380
 
 
381
    off_t offset = 0;
 
382
    size_t remaining = length;
 
383
    uint failure_cnt = 0;
 
384
    while ((remaining > 0) && (failure_cnt < 5))
 
385
    {
 
386
        ssize_t written = file.write(data.data() + offset, remaining);
 
387
        if (written < 0)
 
388
        {
 
389
            failure_cnt++;
 
390
            usleep(50000);
 
391
            continue;
 
392
        }
 
393
 
 
394
        failure_cnt  = 0;
 
395
        offset      += written;
 
396
        remaining   -= written;
 
397
    }
 
398
 
 
399
    if (remaining)
 
400
    {
 
401
        VERBOSE(VB_IMPORTANT, loc_err +
 
402
                QString("Failed to write cached preview file '%1'")
 
403
                .arg(cachefile));
 
404
 
 
405
        file.resize(0); // in case unlink fails..
 
406
        file.remove();  // closes fd
 
407
        return QDateTime();
 
408
    }
 
409
 
 
410
    file.close();
 
411
 
 
412
    return retdatetime;
 
413
}
 
414
 
290
415
void RemoteFillProginfo(ProgramInfo *pginfo, const QString &playbackhostname)
291
416
{
292
417
    QStringList strlist( "FILL_PROGRAM_INFO" );
371
496
    return strlist[0].toInt();
372
497
}
373
498
 
 
499
static QMutex sgroupMapLock;
 
500
static QHash <QString, QString>sgroupMap;
 
501
 
 
502
void RemoteClearSGMap(void)
 
503
{
 
504
    QMutexLocker locker(&sgroupMapLock);
 
505
    sgroupMap.clear();
 
506
}
 
507
 
 
508
QString GetHostSGToUse(QString host, QString sgroup)
 
509
{
 
510
    QString tmpGroup = sgroup;
 
511
    QString groupKey = QString("%1:%2").arg(sgroup, host);
 
512
 
 
513
    QMutexLocker locker(&sgroupMapLock);
 
514
 
 
515
    if (sgroupMap.contains(groupKey))
 
516
    {
 
517
        tmpGroup = sgroupMap[groupKey];
 
518
    }
 
519
    else
 
520
    {
 
521
        if (StorageGroup::FindDirs(sgroup, host))
 
522
        {
 
523
            sgroupMap[groupKey] = sgroup;
 
524
        }
 
525
        else
 
526
        {
 
527
            VERBOSE(VB_FILE+VB_EXTRA, QString("GetHostSGToUse(): "
 
528
                    "falling back to Videos Storage Group for host %1 "
 
529
                    "since it does not have a %2 Storage Group.")
 
530
                    .arg(host).arg(sgroup));
 
531
 
 
532
            tmpGroup = "Videos";
 
533
            sgroupMap[groupKey] = tmpGroup;
 
534
        }
 
535
    }
 
536
 
 
537
    return tmpGroup;
 
538
}
 
539
 
 
540
bool RemoteGetFileList(QString host, QString path, QStringList* list,
 
541
                       QString sgroup, bool fileNamesOnly)
 
542
{
 
543
 
 
544
    // Make sure the list is empty when we get started
 
545
    list->clear();
 
546
 
 
547
    if (sgroup.isEmpty())
 
548
        sgroup = "Videos";
 
549
 
 
550
    *list << "QUERY_SG_GETFILELIST";
 
551
    *list << host;
 
552
    *list << GetHostSGToUse(host, sgroup);
 
553
    *list << path;
 
554
    *list << QString::number(fileNamesOnly);
 
555
 
 
556
    bool ok = gContext->SendReceiveStringList(*list);
 
557
 
 
558
// Should the SLAVE UNREACH test be here ?
 
559
    return ok;
 
560
}
 
561
 
 
562
QString RemoteGenFileURL(QString sgroup, QString host, QString path)
 
563
{
 
564
    return QString("myth://%1@").arg(GetHostSGToUse(host, sgroup)) +
 
565
              gContext->GetSettingOnHost("BackendServerIP", host) + ":" +
 
566
              gContext->GetSettingOnHost("BackendServerPort", host) + "/" +
 
567
              path;
 
568
 
 
569
}
 
570
 
374
571
/**
375
572
 * Get recorder for a programme.
376
573
 *