~vanvugt/+junk/mediatomb

« back to all changes in this revision

Viewing changes to src/tools.cc

  • Committer: Bazaar Package Importer
  • Author(s): Andres Mejia
  • Date: 2008-03-02 13:09:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080302130916-zlljdze3kt7vuq4b
Tags: 0.11.0-1
* New upstream release.
* Include message about which inotify headers will be used when enabling
  inotify runtime support.
* Fixed error with use of INTERFACE in init script. Also removed use of -m
  option.
* Including new config.xml options.
* Added more build dependencies for new upstream release.
* Removed build dependency of libid3-dev, taglib is now preferred.
* mediatomb.xpm and manpage.xml is now included in orig tarball.
* inotify patch is not needed anymore.
* md5 patch has been committed upstream and is no longer needed. Also removed
  README.Debian.
* TwinHelix PNG fix is now used. Removed from TODO.
* Adding dependency of iceweasel for mediatomb package.
* Updated copyright file.
* Updated watch file.
* Updated rules file for proper configure options.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
    Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
8
8
                       Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
9
9
    
10
 
    Copyright (C) 2006-2007 Gena Batyan <bgeradz@mediatomb.cc>,
 
10
    Copyright (C) 2006-2008 Gena Batyan <bgeradz@mediatomb.cc>,
11
11
                            Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
12
12
                            Leonhard Wimmer <leo@mediatomb.cc>
13
13
    
24
24
    version 2 along with MediaTomb; if not, write to the Free Software
25
25
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
26
26
    
27
 
    $Id: tools.cc 1394 2007-07-12 19:00:18Z lww $
 
27
    $Id: tools.cc 1702 2008-02-23 22:00:57Z lww $
28
28
*/
29
29
 
30
30
/// \file tools.cc
43
43
#include <arpa/inet.h>
44
44
#include <limits.h>
45
45
#include <netdb.h>
 
46
#include <string.h>
 
47
 
46
48
#ifndef SOLARIS
47
49
    #include <net/if.h>
48
50
#else
59
61
 
60
62
using namespace zmm;
61
63
 
62
 
static char *HEX_CHARS = "0123456789abcdef";
 
64
static const char *HEX_CHARS = "0123456789abcdef";
63
65
 
64
 
Ref<Array<StringBase> > split_string(String str, char sep)
 
66
Ref<Array<StringBase> > split_string(String str, char sep, bool empty)
65
67
{
66
68
    Ref<Array<StringBase> > ret(new Array<StringBase>());
67
69
    char *data = str.c_str();
78
80
        else if (pos == data)
79
81
        {
80
82
            data++;
 
83
            if ((data < end) && empty)
 
84
                ret->append(String(""));
81
85
        }
82
86
        else
83
87
        {
163
167
    return true;
164
168
}
165
169
 
166
 
time_t check_path_ex(String path, bool needDir, bool existenceUnneeded)
 
170
time_t check_path_ex(String path, bool needDir, bool existenceUnneeded, 
 
171
        off_t *filesize)
167
172
{
168
173
    int ret = 0;
169
174
    struct stat statbuf;
170
175
 
 
176
    if (filesize != NULL)
 
177
        *filesize = 0;
 
178
 
171
179
    ret = stat(path.c_str(), &statbuf);
172
 
    log_debug("path: %s, ret: %d; errno: %d\n", path.c_str(), ret, errno);
173
 
    
174
180
    if (ret != 0)
175
181
    {
176
182
        if (existenceUnneeded && (errno == ENOENT))
177
183
            return 0;
178
184
        
179
 
        throw _Exception(path + " : " + errno + (int)existenceUnneeded+ " x " + strerror(errno));
 
185
        throw _Exception(path + " : " + errno + (int)existenceUnneeded+ " x " + mt_strerror(errno));
180
186
    }
181
187
 
182
188
    if (needDir && (!S_ISDIR(statbuf.st_mode)))
185
191
    if (!needDir && (S_ISDIR(statbuf.st_mode)))
186
192
        throw _Exception(_("Not a file: ") + path);
187
193
 
 
194
    if ((filesize != NULL) && S_ISREG(statbuf.st_mode))
 
195
        *filesize = statbuf.st_size;
 
196
 
188
197
    return statbuf.st_mtime;
189
198
}
190
199
 
 
200
bool is_executable(String path, int *err)
 
201
{
 
202
    int ret = access(path.c_str(), R_OK | X_OK);
 
203
    if (err != NULL)
 
204
        *err = errno;
 
205
 
 
206
    if (ret == 0)
 
207
        return true;
 
208
    else 
 
209
        return false;
 
210
}
 
211
 
 
212
String find_in_path(String exec)
 
213
{
 
214
    String PATH = String(getenv("PATH"));
 
215
    if (!string_ok(PATH))
 
216
        return nil;
 
217
 
 
218
    Ref<StringTokenizer> st(new StringTokenizer(PATH));
 
219
    String path = nil;
 
220
    String next;
 
221
    do
 
222
    {
 
223
        if (path == nil)
 
224
            path = st->nextToken(_(":"));
 
225
        next = st->nextToken(_(":"));
 
226
 
 
227
        if (path == nil)
 
228
            break;
 
229
 
 
230
        if ((next != nil) && !next.startsWith(_("/")))
 
231
        {
 
232
            path = path + _(":") + next;
 
233
            next = nil;
 
234
        }
 
235
 
 
236
        String check = path + _("/") + exec;
 
237
        if (check_path(check))
 
238
            return check;
 
239
 
 
240
        if (next != nil)
 
241
            path = next;
 
242
        else
 
243
            path = nil;
 
244
 
 
245
 
 
246
    } while (path != nil);
 
247
 
 
248
    return nil;
 
249
}
 
250
 
191
251
bool string_ok(String str)
192
252
{
193
253
    if ((str == nil) || (str == ""))
380
440
    return buf->toString();
381
441
}
382
442
 
 
443
String mt_strerror(int mt_errno)
 
444
{
 
445
#ifdef DONT_USE_YET_HAVE_STRERROR_R
 
446
    char *buffer = (char *)MALLOC(512);
 
447
    char *err_str;
 
448
    #ifdef STRERROR_R_CHAR_P
 
449
        err_str = strerror_r(errno, buffer, 512);
 
450
        if (err_str == NULL)
 
451
            err_str = buffer;
 
452
    #else
 
453
        int ret = strerror_r(errno, buffer, 512);
 
454
        if (ret < 0)
 
455
            return _("cannot get error string: error while calling XSI-compliant strerror_r");
 
456
        err_str = buffer;
 
457
    #endif
 
458
    String errStr(err_str);
 
459
    FREE(buffer);
 
460
    return errStr;
 
461
#else
 
462
    return String(strerror(errno));
 
463
#endif
 
464
}
 
465
 
383
466
String read_text_file(String path)
384
467
{
385
468
    FILE *f = fopen(path.c_str(), "r");
386
469
    if (!f)
387
470
    {
388
471
        throw _Exception(_("read_text_file: could not open ") +
389
 
                        path + " : " + strerror(errno));
 
472
                        path + " : " + mt_strerror(errno));
390
473
    }
391
474
    Ref<StringBuffer> buf(new StringBuffer()); 
392
475
    char *buffer = (char *)MALLOC(1024);
393
 
    int bytesRead;    
 
476
    size_t bytesRead;    
394
477
    while((bytesRead = fread(buffer, 1, 1024, f)) > 0)
395
478
    {
396
 
        *buf << String(buffer, bytesRead);
 
479
        buf->concat(buffer, bytesRead);
397
480
    }
398
481
    fclose(f);
399
482
    FREE(buffer);
406
489
    if (!f)
407
490
    {
408
491
        throw _Exception(_("write_text_file: could not open ") +
409
 
                        path + " : " + strerror(errno));
 
492
                        path + " : " + mt_strerror(errno));
410
493
    }
411
494
    
412
495
    bytesWritten = fwrite(contents.c_str(), 1, contents.length(), f);
418
501
                            path + " : ");
419
502
        else
420
503
            throw _Exception(_("write_text_file: error writing to ") +
421
 
                            path + " : " + strerror(errno));
 
504
                            path + " : " + mt_strerror(errno));
422
505
    }
423
506
    fclose(f);
424
507
}
425
508
 
 
509
void copy_file(String from, String to)
 
510
{
 
511
    FILE *f = fopen(from.c_str(), "r");
 
512
    if (!f)
 
513
    {
 
514
        throw _Exception(_("copy_file: could not open ") +
 
515
                        from + " for read: " + mt_strerror(errno));
 
516
    }
 
517
    FILE *t = fopen(to.c_str(), "w");
 
518
    if (!t)
 
519
    {
 
520
        fclose(f);
 
521
        throw _Exception(_("copy_file: could not open ") +
 
522
                        to + " for write: " + mt_strerror(errno));
 
523
    }
 
524
    char *buffer = (char *)MALLOC(1024);
 
525
    size_t bytesRead = 0;
 
526
    size_t bytesWritten = 0;
 
527
    while(bytesRead == bytesWritten && ! feof(f) && ! ferror(f) && ! ferror(t)
 
528
        && (bytesRead = fread(buffer, 1, 1024, f)) > 0)
 
529
    {
 
530
        bytesWritten = fwrite(buffer, 1, bytesRead, t);
 
531
    }
 
532
    FREE(buffer);
 
533
    if (ferror(f) || ferror(t))
 
534
    {
 
535
        int my_errno = errno;
 
536
        fclose(f);
 
537
        fclose(t);
 
538
        throw _Exception(_("copy_file: error while copying ") + from + " to " +
 
539
                        to + ": " + mt_strerror(my_errno));
 
540
    }
 
541
    
 
542
    fclose(f);
 
543
    fclose(t);
 
544
}
426
545
 
427
546
/* sorting */
428
547
int StringBaseComparator(void *arg1, void *arg2)
513
632
        return _("http-get:*:*:*");
514
633
}
515
634
 
 
635
String getMTFromProtocolInfo(String protocol)
 
636
{
 
637
    Ref<Array<StringBase> > parts = split_string(protocol, ':');
 
638
    if (parts->size() > 2)
 
639
        return parts->get(2);
 
640
    else
 
641
        return nil;
 
642
}
 
643
 
516
644
String getProtocol(String protocolInfo)
517
645
{
518
646
    String protocol;
609
737
    }
610
738
}
611
739
 
 
740
bool check_resolution(String resolution, int *x, int *y)
 
741
{
 
742
    if (x != NULL)
 
743
        *x = 0;
 
744
 
 
745
    if (y != NULL)
 
746
        *y = 0;
 
747
 
 
748
    Ref<Array<StringBase> > parts = split_string(resolution, 'x');
 
749
    if (parts->size() != 2)
 
750
        return false;
 
751
 
 
752
    if (string_ok(parts->get(0)) && 
 
753
        string_ok(parts->get(1)))
 
754
        {
 
755
            int _x = String(parts->get(0)->data).toInt();
 
756
            int _y = String(parts->get(1)->data).toInt();
 
757
 
 
758
            if ((_x > 0) && (_y > 0))
 
759
            {
 
760
                if (x != NULL)
 
761
                    *x = _x;
 
762
 
 
763
                if (y != NULL)
 
764
                    *y = _y;
 
765
 
 
766
                return true;
 
767
            }
 
768
        }
 
769
        
 
770
    return false;
 
771
}
 
772
 
 
773
 
612
774
String escape(String string, char escape_char, char to_escape)
613
775
{
614
776
    Ref<StringBase> stringBase(new StringBase(string.length() * 2));
1036
1198
        return true;
1037
1199
}
1038
1200
 
 
1201
Ref<Array<StringBase> > parseCommandLine(String line, String in, String out)
 
1202
{
 
1203
    Ref<Array<StringBase> > params = split_string(line, ' ');
 
1204
    for (int i = 0; i < params->size(); i++)
 
1205
    {
 
1206
        String param = params->get(i);
 
1207
        String newParam = param.replace(_("%in"), in);
 
1208
        newParam = newParam.replace(_("%out"), out);
 
1209
        if (param != newParam)
 
1210
            params->set(newParam, i);
 
1211
    }
 
1212
 
 
1213
    return params;
 
1214
}
 
1215
 
 
1216
// The tempName() function is borrowed from gfileutils.c from the glibc package
 
1217
 
 
1218
/* gfileutils.c - File utility functions
 
1219
 *
 
1220
 *  Copyright 2000 Red Hat, Inc.
 
1221
 *
 
1222
 * GLib is free software; you can redistribute it and/or modify it
 
1223
 * under the terms of the GNU Lesser General Public License as
 
1224
 * published by the Free Software Foundation; either version 2 of the
 
1225
 * License, or (at your option) any later version.
 
1226
 *
 
1227
 * GLib is distributed in the hope that it will be useful,
 
1228
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
1229
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
1230
 * Lesser General Public License for more details.
 
1231
 *
 
1232
 * You should have received a copy of the GNU Lesser General Public
 
1233
 * License along with GLib; see the file COPYING.LIB.  If not,
 
1234
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
1235
 *   Boston, MA 02111-1307, USA.
 
1236
 */
 
1237
/*
 
1238
 * create_temp_file based on the mkstemp implementation from the GNU C library.
 
1239
 * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
 
1240
 */
 
1241
// tempName is based on create_temp_file, see (C) above
 
1242
String tempName(String leadPath, char *tmpl)
 
1243
{
 
1244
    char *XXXXXX;
 
1245
    int count;
 
1246
    static const char letters[] =
 
1247
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
1248
    static const int NLETTERS = sizeof (letters) - 1;
 
1249
    long value;
 
1250
    struct timeval tv;
 
1251
    static int counter = 0;
 
1252
    struct stat statbuf;
 
1253
    int ret = 0;
 
1254
 
 
1255
    /* find the last occurrence of "XXXXXX" */
 
1256
    XXXXXX = strstr (tmpl, "XXXXXX");
 
1257
 
 
1258
    if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
 
1259
    {
 
1260
        return nil;
 
1261
    }
 
1262
 
 
1263
    /* Get some more or less random data.  */
 
1264
    gettimeofday(&tv, NULL);
 
1265
    value = (tv.tv_usec ^ tv.tv_sec) + counter++;
 
1266
 
 
1267
    for (count = 0; count < 100; value += 7777, ++count)
 
1268
    {
 
1269
        long v = value;
 
1270
 
 
1271
        /* Fill in the random bits.  */
 
1272
        XXXXXX[0] = letters[v % NLETTERS];
 
1273
        v /= NLETTERS;
 
1274
        XXXXXX[1] = letters[v % NLETTERS];
 
1275
        v /= NLETTERS;
 
1276
        XXXXXX[2] = letters[v % NLETTERS];
 
1277
        v /= NLETTERS;
 
1278
        XXXXXX[3] = letters[v % NLETTERS];
 
1279
        v /= NLETTERS;
 
1280
        XXXXXX[4] = letters[v % NLETTERS];
 
1281
        v /= NLETTERS;
 
1282
        XXXXXX[5] = letters[v % NLETTERS];
 
1283
 
 
1284
        String check =  leadPath + tmpl;
 
1285
        ret = stat(check.c_str(), &statbuf);
 
1286
        if (ret != 0)
 
1287
        {
 
1288
            if ((errno == ENOENT) ||
 
1289
                    (errno == ENOTDIR))
 
1290
                return check;
 
1291
            else
 
1292
                return nil;
 
1293
        }
 
1294
    }
 
1295
 
 
1296
    /* We got out of the loop because we ran out of combinations to try.  */
 
1297
    return nil;
 
1298
}
 
1299
 
 
1300
bool isTheora(String ogg_filename)
 
1301
{
 
1302
    FILE *f;
 
1303
    char buffer[7];
 
1304
    f = fopen(ogg_filename.c_str(), "rb");
 
1305
    
 
1306
    if (fread(buffer, 1, 4, f) != 4)
 
1307
    {
 
1308
        fclose(f);
 
1309
        throw _Exception(_("Error reading ") + ogg_filename);
 
1310
    }
 
1311
 
 
1312
    if (memcmp(buffer, "OggS", 4) != 0)
 
1313
    {
 
1314
        fclose(f);
 
1315
        return false;
 
1316
    }
 
1317
 
 
1318
    if (fseek(f, 28, SEEK_SET) != 0)
 
1319
    {
 
1320
        fclose(f);
 
1321
        throw _Exception(_("Incomplete file ") + ogg_filename);
 
1322
    }
 
1323
 
 
1324
    if (fread(buffer, 1, 7, f) != 7)
 
1325
    {
 
1326
        fclose(f);
 
1327
        throw _Exception(_("Error reading ") + ogg_filename);
 
1328
    }
 
1329
 
 
1330
    if (memcmp(buffer, "\x80theora", 7) != 0)
 
1331
    {
 
1332
        fclose(f);
 
1333
        return false;
 
1334
    }
 
1335
 
 
1336
    fclose(f);
 
1337
    return true;
 
1338
}
 
1339
 
 
1340
#ifndef HAVE_FFMPEG
 
1341
String getAVIFourCC(zmm::String avi_filename)
 
1342
{
 
1343
#define FCC_OFFSET  0xbc
 
1344
    char *buffer;
 
1345
    FILE *f = fopen(avi_filename.c_str(), "rb");
 
1346
    if (!f)
 
1347
        throw _Exception(_("could not open file ") + avi_filename + " : " +
 
1348
                          mt_strerror(errno));
 
1349
 
 
1350
    buffer = (char *)MALLOC(FCC_OFFSET+6);
 
1351
    if (buffer == NULL)
 
1352
    {
 
1353
        fclose(f);
 
1354
        throw _Exception(_("Out of memory when allocating buffer for file ") +
 
1355
                          avi_filename);
 
1356
    }
 
1357
 
 
1358
    size_t rb = fread(buffer, 1, FCC_OFFSET+4, f);
 
1359
    fclose(f);
 
1360
    if (rb != FCC_OFFSET+4)
 
1361
    {
 
1362
        free(buffer);
 
1363
        throw _Exception(_("could not read header of ") + avi_filename +  
 
1364
                          " : " + mt_strerror(errno));
 
1365
    }
 
1366
 
 
1367
    buffer[FCC_OFFSET+5] = '\0';
 
1368
 
 
1369
    if (strncmp(buffer, "RIFF", 4) != 0)
 
1370
    {
 
1371
        free(buffer);
 
1372
        return nil;
 
1373
    }
 
1374
 
 
1375
    if (strncmp(buffer+8, "AVI ", 4) != 0)
 
1376
    {
 
1377
        free(buffer);
 
1378
        return nil;
 
1379
    }
 
1380
 
 
1381
    String fourcc = String(buffer+FCC_OFFSET, 4);
 
1382
    free(buffer);
 
1383
 
 
1384
    if (string_ok(fourcc))
 
1385
        return fourcc;
 
1386
    else
 
1387
        return nil;
 
1388
}
 
1389
#endif
 
1390
 
1039
1391
#ifdef LOG_TOMBDEBUG
1040
1392
 
1041
1393
void profiling_thread_check(struct profiling_t *data)