~vanvugt/+junk/mediatomb

« back to all changes in this revision

Viewing changes to src/main.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: main.cc 1381 2007-07-08 16:06:02Z lww $
 
27
    $Id: main.cc 1699 2008-02-23 21:01:32Z lww $
28
28
*/
29
29
 
30
30
/// \file main.cc
31
31
 
32
32
/// \mainpage Sourcecode Documentation.
33
33
///
34
 
/// This documentation was generated using doxygen, you can repdoruce it by 
 
34
/// This documentation was generated using doxygen, you can reproduce it by 
35
35
/// running "doxygen doxygen.conf" from the mediatomb/doc/ directory.
36
36
 
37
37
#ifdef HAVE_CONFIG_H
61
61
#include <unistd.h>
62
62
#include <syslog.h>
63
63
#include <string.h>
 
64
#include <pthread.h>
64
65
#include <signal.h>
65
66
#include <pwd.h>
66
67
#include <grp.h>
87
88
    struct   sigaction action;
88
89
    sigset_t mask_set;
89
90
 
 
91
    int      devnull;
90
92
    struct   passwd *pwd;
91
93
    struct   group  *grp;
92
94
#ifdef HAVE_GETOPT_LONG
118
120
    String pid_file;
119
121
    String interface;
120
122
    String ip;
 
123
    String prefix;
 
124
    String magic;
121
125
 
122
126
    Ref<Array<StringBase> > addFile(new Array<StringBase>());
 
127
 
 
128
#ifdef SOLARIS
 
129
    String ld_preload;
 
130
    char *preload = getenv("LD_PRELOAD");
 
131
    if (preload != NULL)
 
132
        ld_preload = String(preload);
 
133
 
 
134
    if ((preload == NULL) || (ld_preload.find("0@0") != -1))
 
135
    {
 
136
        printf("MediaTomb: Solaris check failed!\n");
 
137
        printf("Please set the environment to match glibc behaviour!\n");
 
138
        printf("LD_PRELOAD=/usr/lib/0@0.so.1\n");
 
139
        exit(EXIT_FAILURE);
 
140
    }
 
141
#endif
 
142
 
123
143
#ifdef HAVE_GETOPT_LONG   
124
144
    while (1)
125
145
    {
150
170
 
151
171
                if (port > USHRT_MAX)
152
172
                {
153
 
                    log_error("Invalid port value %d. Maximum allowed port value is %d\n",
154
 
                                USHRT_MAX);
 
173
                    log_error("Invalid port value %d. Maximum allowed port value is %d\n", port, USHRT_MAX);
155
174
                }
156
175
                log_debug("port set to: %d\n", port);
157
176
                break;
211
230
    --config or -c     configuration file to use\n\
212
231
    --daemon or -d     run server in background\n\
213
232
    --home or -m       define the home directory\n\
214
 
    --cfgdir or -f    name of the directory that is holding the configuration\n\
 
233
    --cfgdir or -f     name of the directory that is holding the configuration\n\
215
234
    --pidfile or -P    file to hold the process id\n\
216
235
    --user or -u       run server under specified username\n\
217
236
    --group or -g      run server under specified group\n\
236
255
        printf("\nMediaTomb UPnP Server version %s - %s\n\n", VERSION, 
237
256
                DESC_MANUFACTURER_URL);
238
257
        printf("===============================================================================\n");
239
 
        printf("Copyright 2005-2007 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer.\n");
 
258
        printf("Copyright 2005-2008 Gena Batsyan, Sergey Bostandzhyan, Leonhard Wimmer.\n");
240
259
        printf("MediaTomb is free software, covered by the GNU General Public License version 2\n\n");
241
260
    }
242
261
 
243
 
// check if user and/or group parameter was specified and try to run the server
 
262
    // check if user and/or group parameter was specified and try to run the server
244
263
    // under the given user and/or group name
245
264
    if (group != nil)
246
265
    {
250
269
            log_error("Group %s not found!\n", group.c_str());
251
270
            exit(EXIT_FAILURE);
252
271
        }
253
 
 
 
272
        
254
273
        if (setgid(grp->gr_gid) < 0)
255
274
        {
256
275
            log_error("setgid failed %s\n", strerror(errno));
257
276
            exit(EXIT_FAILURE);
258
277
        }
 
278
        
 
279
        // remove supplementary groups
 
280
        if (setgroups(0, NULL) < 0)
 
281
        {
 
282
            log_error("setgroups failed %s\n", strerror(errno));
 
283
            exit(EXIT_FAILURE);
 
284
        }
259
285
    }
260
 
 
 
286
    
261
287
    if (user != nil)
262
288
    {
263
 
        pwd = getpwnam(user.c_str()); 
 
289
        pwd = getpwnam(user.c_str());
264
290
        if (pwd == NULL)
265
291
        {
266
292
            log_error("User %s not found!\n", user.c_str());
267
293
            exit(EXIT_FAILURE);
268
294
        }
269
 
 
 
295
        
 
296
        // set supplementary groups
 
297
        if (initgroups(user.c_str(), getegid()) < 0)
 
298
        {
 
299
            log_error("initgroups failed %s\n", strerror(errno));
 
300
            exit(EXIT_FAILURE);
 
301
        }
 
302
        
270
303
        if (setuid(pwd->pw_uid) < 0)
271
304
        {
272
305
            log_error("setuid failed %s\n", strerror(errno));
278
311
    try
279
312
    {
280
313
        // if home is not given by the user, get it from the environment
281
 
        if (!string_ok(home))
 
314
        if (!string_ok(home) && (!string_ok(config_file)))
282
315
        {
283
316
#ifndef __CYGWIN__
284
317
            char *h = getenv("HOME");
294
327
#endif  // __CYGWIN__
295
328
        }
296
329
 
297
 
        if (!string_ok(home))
 
330
        if (!string_ok(home) && (!string_ok(config_file)))
298
331
        {
299
332
            log_error("Could not determine users home directory\n");
300
333
            exit(EXIT_FAILURE);
303
336
        if (!string_ok(confdir))
304
337
            confdir = _(DEFAULT_CONFIG_HOME);
305
338
 
306
 
/*        if ((config_file == nil) && (home == nil))
307
 
        {
308
 
            log_info("No configuration specified and no user home directory set.\n");
309
 
            exit(EXIT_FAILURE);
310
 
        }
311
 
        
312
 
*/
313
 
        ConfigManager::setStaticArgs(config_file, home, confdir);
 
339
        char *pref = getenv("MEDIATOMB_DATADIR");
 
340
        if (pref != NULL)
 
341
            prefix = String(pref);
 
342
 
 
343
        if (!string_ok(prefix))
 
344
            prefix = _(PACKAGE_DATADIR);
 
345
 
 
346
        char *mgc = getenv("MEDIATOMB_MAGIC_FILE");
 
347
        if (mgc != NULL)
 
348
            magic = String(mgc);
 
349
 
 
350
        if (!string_ok(magic))
 
351
            magic = nil;
 
352
 
 
353
        ConfigManager::setStaticArgs(config_file, home, confdir, prefix, magic);
314
354
        ConfigManager::getInstance();
315
355
    }
316
356
    catch (mxml::ParseException pe)
340
380
 
341
381
        /* Fork off the parent process */
342
382
        pid = fork();
343
 
        if (pid < 0) {
 
383
        if (pid < 0) 
 
384
        {
 
385
            log_error("Failed to fork: %s\n", strerror(errno));
344
386
            exit(EXIT_FAILURE);
345
387
        }
346
388
        /* If we got a good PID, then
347
389
           we can exit the parent process. */
348
 
        if (pid > 0) {
 
390
        if (pid > 0) 
 
391
        {
349
392
            exit(EXIT_SUCCESS);
350
393
        }
351
394
 
352
395
        /* Change the file mode mask */
353
 
        umask(0);
 
396
        umask(0133);
354
397
 
355
398
        /* Open any logs here */        
356
399
 
357
400
        /* Create a new SID for the child process */
358
401
        sid = setsid();
359
 
        if (sid < 0) {
360
 
            /* Log the failure */
 
402
        if (sid < 0) 
 
403
        {
 
404
            log_error("setsid failed: %s\n", strerror(errno));
361
405
            exit(EXIT_FAILURE);
362
406
        }
363
407
 
364
408
        /* Change the current working directory */
365
 
        if ((chdir("/")) < 0) {
366
 
            /* Log the failure */
 
409
        if ((chdir("/")) < 0) 
 
410
        {
 
411
            log_error("Failed to chdir to / : %s\n", strerror(errno));
367
412
            exit(EXIT_FAILURE);
368
413
        }
369
414
 
371
416
        close(STDIN_FILENO);
372
417
        close(STDOUT_FILENO);
373
418
        close(STDERR_FILENO);
 
419
 
 
420
        devnull = open("/dev/null", O_RDWR);
 
421
        if (devnull == -1)
 
422
        {
 
423
            log_error("Failed to open /dev/null: %s\n", strerror(errno));
 
424
        }
 
425
        dup(devnull);
 
426
        dup(devnull);
374
427
    }
375
428
 
376
429
    if (pid_file != nil)
411
464
    {
412
465
        log_error("Could not register SIGINT handler!\n");
413
466
    }
 
467
 
414
468
    if (sigaction(SIGTERM, &action, NULL) < 0)
415
469
    {
416
470
        log_error("Could not register SIGTERM handler!\n");
417
471
    }
 
472
 
418
473
    if (sigaction(SIGHUP, &action, NULL) < 0)
419
474
    {
420
475
        log_error("Could not register SIGHUP handler!\n");
421
476
    }
 
477
 
422
478
    if (sigaction(SIGPIPE, &action, NULL) < 0)
423
479
    {
424
480
        log_error("Could not register SIGPIPE handler!\n");
425
481
    }
426
482
 
427
 
 
428
 
 
429
 
 
430
 
    // prepare to run processes
431
 
    init_process();
432
 
    
433
483
    Ref<SingletonManager> singletonManager = SingletonManager::getInstance();
434
484
    Ref<Server> server;
435
485
    try
467
517
            log_error("%s\n", e.getMessage().c_str());
468
518
            e.printStackTrace();
469
519
        }
 
520
        if (daemon)
 
521
            close(devnull);
470
522
        exit(EXIT_FAILURE);
471
523
    }
472
524
    catch (Exception e)
473
525
    {
474
526
        log_error("%s\n", e.getMessage().c_str());
475
527
        e.printStackTrace();
 
528
        if (daemon)
 
529
            close(devnull);
476
530
        exit(EXIT_FAILURE);
477
531
    }
478
532
 
491
545
            catch (Exception e)
492
546
            {
493
547
                e.printStackTrace();
 
548
                if (daemon)
 
549
                    close(devnull);
494
550
                exit(EXIT_FAILURE);
495
551
            }
496
552
        }
524
580
                
525
581
                try
526
582
                {
527
 
                    ConfigManager::setStaticArgs(config_file, home, confdir);
 
583
                    ConfigManager::setStaticArgs(config_file, home, confdir, 
 
584
                                                 prefix, magic);
528
585
                    ConfigManager::getInstance();
529
586
                }
530
587
                catch (mxml::ParseException pe)
543
600
                    log_error("Error reloading configuration: %s\n", 
544
601
                              e.getMessage().c_str());
545
602
                    e.printStackTrace();
 
603
                    if (daemon)
 
604
                        close(devnull);
546
605
                    exit(EXIT_FAILURE);
547
606
                }
548
607
                
549
 
                init_process();
550
 
                
551
608
                ///  \todo fix this for SIGHUP
552
609
                server = Server::getInstance();
553
610
                server->upnp_init(interface, ip, port);
561
618
                sigemptyset(&mask_set);
562
619
                pthread_sigmask(SIG_SETMASK, &mask_set, NULL);
563
620
                log_error("Could not restart MediaTomb\n");
564
 
 
565
621
            }
566
622
        }
567
623
    }
585
641
 
586
642
    log_info("Server terminating\n");
587
643
    log_close();
588
 
    
589
 
    return ret;
 
644
 
 
645
    if (daemon)
 
646
        close(devnull);
 
647
 
 
648
    exit(ret);
590
649
}
591
650
 
592
651
void signal_handler(int signum)