34 #include <sys/types.h> 36 #include <sys/ioctl.h> 39 #if defined(__linux__) || defined(__LINUX__) 40 #include <sys/prctl.h> 50 #include <QVariantList> 51 #include <QVariantMap> 53 #include <QCoreApplication> 54 #include <QTextStream> 80 bool setUser(
const QString &username);
88 #if defined(_WIN32) || defined(Q_OS_ANDROID) 93 if (ioctl(0, TIOCGWINSZ, &ws) != 0)
96 return (
int)ws.ws_col;
120 return "kCombOptVal";
126 return "kPassthrough";
171 QVariant def, QString
help, QString longhelp) :
174 m_group(
""), m_deprecated(
""), m_removed(
""), m_removedversion(
""),
175 m_type(
type), m_default(def), m_help(
help), m_longhelp(longhelp)
177 if ((
m_type != QVariant::String) && (
m_type != QVariant::StringList) &&
178 (
m_type != QVariant::Map))
191 m_group(
""), m_deprecated(
""), m_removed(
""), m_removedversion(
""),
192 m_type(
type), m_default(def)
194 if ((
m_type != QVariant::String) && (
m_type != QVariant::StringList) &&
195 (
m_type != QVariant::Map))
209 m_deprecated(
""), m_removed(
""), m_removedversion(
""),
210 m_type(QVariant::Invalid)
231 QList<CommandLineArg*>::const_iterator i1;
233 len = max(len, (*i1)->GetKeywordLength()+2);
256 QTextStream msg(&helpstr, QIODevice::WriteOnly);
295 QStringList hlist =
m_help.split(
'\n');
303 QStringList::const_iterator i1;
304 for (i1 = hlist.begin() + 1; i1 != hlist.end(); ++i1)
305 msg << pad << *i1 << endl;
308 QList<CommandLineArg*>::const_iterator i2;
310 msg << (*i2)->GetHelpString(off, group,
true);
326 QTextStream msg(&helpstr, QIODevice::WriteOnly);
340 msg <<
"Option: " << keyword << endl << endl;
345 QStringList::const_iterator i1;
352 msg <<
"Aliases: " << *i1 << endl;
356 msg <<
" " << *i1 << endl;
361 msg <<
"Type: " << QVariant::typeToName(
m_type) << endl;
362 if (
m_default.canConvert(QVariant::String))
363 msg <<
"Default: " <<
m_default.toString() << endl;
373 msg <<
"Description: " <<
help[0] << endl;
374 for (i1 =
help.begin() + 1; i1 !=
help.end(); ++i1)
375 msg <<
" " << *i1 << endl;
377 QList<CommandLineArg*>::const_iterator i2;
382 msg << endl <<
"Can be used in combination with:" << endl;
384 msg <<
" " << (*i2)->GetPreferredKeyword()
385 .toLocal8Bit().constData();
391 msg << endl <<
"Allows the use of:" << endl;
393 msg <<
" " << (*i2)->GetPreferredKeyword()
394 .toLocal8Bit().constData();
400 msg << endl <<
"Requires the use of:" << endl;
402 msg <<
" " << (*i2)->GetPreferredKeyword()
403 .toLocal8Bit().constData();
409 msg << endl <<
"Prevents the use of:" << endl;
411 msg <<
" " << (*i2)->GetPreferredKeyword()
412 .toLocal8Bit().constData();
443 case QVariant::String:
448 cerr <<
"Command line option did not receive value:" << endl
449 <<
" " << opt.toLocal8Bit().constData() << endl;
462 QList<QByteArray> blist;
469 cerr <<
"Boolean type options do not accept values:" << endl
470 <<
" " << opt.toLocal8Bit().constData() << endl;
473 case QVariant::String:
485 case QVariant::LongLong:
486 m_stored = QVariant(val.toLongLong());
489 case QVariant::Double:
490 m_stored = QVariant(val.toDouble());
493 case QVariant::DateTime:
497 case QVariant::StringList:
505 if (!val.contains(
'='))
507 cerr <<
"Command line option did not get expected " 508 <<
"key/value pair" << endl;
512 blist = val.split(
'=');
516 vmap[QString(blist[0])] = QVariant(blist[1]);
521 if (!val.contains(
'x'))
523 cerr <<
"Command line option did not get expected " 524 <<
"XxY pair" << endl;
528 blist = val.split(
'x');
529 m_stored = QVariant(QSize(blist[0].toInt(), blist[1].toInt()));
552 QStringList::const_iterator i =
opts.begin();
553 for (; i !=
opts.end(); ++i)
570 QStringList::const_iterator i =
opts.begin();
571 for (; i !=
opts.end(); ++i)
588 QStringList::const_iterator i =
opts.begin();
589 for (; i !=
opts.end(); ++i)
606 QStringList::const_iterator i =
opts.begin();
607 for (; i !=
opts.end(); ++i)
625 QStringList::const_iterator i =
opts.begin();
626 for (; i !=
opts.end(); ++i)
647 QStringList::const_iterator i =
opts.begin();
648 for (; i !=
opts.end(); ++i)
668 QStringList::const_iterator i =
opts.begin();
669 for (; i !=
opts.end(); ++i)
686 QStringList::const_iterator i =
opts.begin();
687 for (; i !=
opts.end(); ++i)
696 if (depstr.isEmpty())
697 depstr =
"and will be removed in a future version.";
706 if (remstr.isEmpty())
707 remstr =
"and is no longer available in this version.";
721 bool replaced =
false;
750 bool replaced =
false;
779 bool replaced =
false;
809 bool replaced =
false;
812 for (i = 0; i <
m_blocks.size(); i++)
838 QList<CommandLineArg*>::const_iterator i1,i2;
841 for (i1 =
args.begin(); i1 !=
args.end()-1; ++i1)
845 for (i2 = i1+1; i2 !=
args.end(); ++i2)
847 (*i1)->SetBlocks(*i2);
850 if ((*i1)->m_type == QVariant::Invalid)
863 if (!QCoreApplication::instance())
878 if (
m_type == QVariant::String)
880 if (
m_stored.type() == QVariant::ByteArray)
888 else if (
m_type == QVariant::StringList)
890 if (
m_stored.type() == QVariant::List)
892 QVariantList vlist =
m_stored.toList();
893 QVariantList::const_iterator iter = vlist.begin();
895 for (; iter != vlist.end(); ++iter)
896 slist << QString::fromLocal8Bit(iter->toByteArray());
900 else if (
m_type == QVariant::Map)
902 QVariantMap vmap =
m_stored.toMap();
903 QVariantMap::iterator iter = vmap.begin();
904 for (; iter != vmap.end(); ++iter)
905 (*iter) = QString::fromLocal8Bit(iter->toByteArray());
921 QStringList::const_iterator it;
946 QList<CommandLineArg*>::const_iterator i;
961 <<
" requires at least one of the following arguments" << endl;
964 << (*i)->GetPreferredKeyword().toLocal8Bit().constData();
965 cerr << endl << endl;
977 <<
" requires all of the following be defined as well" 981 << (*i)->GetPreferredKeyword().toLocal8Bit()
983 cerr << endl << endl;
994 <<
" requires that none of the following be defined" << endl;
997 << (*i)->GetPreferredKeyword().toLocal8Bit()
999 cerr << endl << endl;
1035 cerr <<
" " <<
m_name.leftJustified(30).toLocal8Bit().constData();
1038 QMap<QString, QVariant> tmpmap;
1039 QMap<QString, QVariant>::const_iterator it;
1041 QVariantList::const_iterator it2;
1046 case QVariant::Bool:
1047 cerr << (
m_stored.toBool() ?
"True" :
"False") << endl;
1054 case QVariant::UInt:
1058 case QVariant::LongLong:
1059 cerr <<
m_stored.toLongLong() << endl;
1062 case QVariant::Double:
1063 cerr <<
m_stored.toDouble() << endl;
1066 case QVariant::Size:
1068 cerr <<
"x=" << tmpsize.width()
1069 <<
" y=" << tmpsize.height()
1073 case QVariant::String:
1074 cerr <<
'"' <<
m_stored.toByteArray().constData()
1078 case QVariant::StringList:
1080 it2 = vlist.begin();
1081 cerr <<
'"' << it2->toByteArray().constData() <<
'"';
1083 for (; it2 != vlist.end(); ++it2)
1094 for (it = tmpmap.begin(); it != tmpmap.end(); ++it)
1099 cerr << QString(
"").leftJustified(32)
1100 .toLocal8Bit().constData();
1102 cerr << it.key().toLocal8Bit().constData()
1104 << it->toByteArray().constData()
1110 case QVariant::DateTime:
1112 .toLocal8Bit().constData()
1125 QString warn = QString(
"%1 has been removed").arg(keyword);
1129 cerr << QString(
"****************************************************\n" 1132 "****************************************************\n\n")
1134 .toLocal8Bit().constData();
1141 cerr << QString(
"****************************************************\n" 1142 " WARNING: %1 has been deprecated\n" 1144 "****************************************************\n\n")
1146 .toLocal8Bit().constData();
1163 m_appname(appname), m_passthroughActive(
false),
1166 char *
verbose = getenv(
"VERBOSE_PARSER");
1169 cerr <<
"MythCommandLineParser is now operating verbosely." << endl;
1178 QMap<QString, CommandLineArg*>::iterator i;
1183 (*i)->CleanupLinks();
1230 QString
name, QVariant::Type
type, QVariant def,
1231 QString
help, QString longhelp)
1243 QStringList::const_iterator i;
1244 for (i = arglist.begin(); i != arglist.end(); ++i)
1250 cerr <<
"Adding " << (*i).toLocal8Bit().constData()
1251 <<
" as taking type '" << QVariant::typeToName(
type)
1265 cout <<
"Please attach all output as a file in bug reports." << endl;
1270 cout <<
"QT Version : " << QT_VERSION_STR << endl;
1271 #ifdef MYTH_BUILD_CONFIG 1272 cout <<
"Options compiled in:" <<endl;
1282 cerr <<
help.toLocal8Bit().constData();
1293 QTextStream msg(&helpstr, QIODevice::WriteOnly);
1295 QString versionStr = QString(
"%1 version: %2 [%3] www.mythtv.org")
1297 msg << versionStr << endl;
1299 if (
toString(
"showhelp").isEmpty())
1304 if (descr.size() > 0)
1305 msg << endl << descr << endl << endl;
1308 QStringList groups(
"");
1310 QMap<QString, CommandLineArg*>::const_iterator i1;
1313 maxlen = max((*i1)->GetKeywordLength(), maxlen);
1314 if (!groups.contains((*i1)->m_group))
1315 groups << (*i1)->m_group;
1321 QStringList::const_iterator i2;
1322 for (i2 = groups.begin(); i2 != groups.end(); ++i2)
1324 if ((*i2).isEmpty())
1325 msg <<
"Misc. Options:" << endl;
1327 msg << (*i2).toLocal8Bit().constData() <<
" Options:" << endl;
1330 msg << (*i1)->GetHelpString(maxlen, *i2);
1337 QString optstr =
"-" +
toString(
"showhelp");
1340 optstr =
"-" + optstr;
1342 return QString(
"Could not find option matching '%1'\n")
1356 int &argpos, QString &opt, QByteArray &val)
1365 QByteArray
tmp(argv[argpos]);
1377 if (
tmp.startsWith(
'-') &&
tmp.size() > 1)
1386 if (
tmp.contains(
'='))
1389 QList<QByteArray> blist =
tmp.split(
'=');
1391 if (blist.size() != 2)
1398 opt = QString(blist[0]);
1405 if (argpos+1 >= argc)
1409 tmp = QByteArray(argv[++argpos]);
1414 if (
tmp.startsWith(
"-") &&
tmp.size() > 1)
1451 for (
int argpos = 1; argpos < argc; ++argpos)
1455 res =
getOpt(argc, argv, argpos, opt, val);
1459 <<
"opt: " << opt.toLocal8Bit().constData() << endl
1460 <<
"val: " << val.constData() << endl << endl;
1465 cerr <<
"Received '--' but passthrough has not been enabled" << endl;
1482 cerr <<
"Invalid option received:" << endl <<
" " 1483 << opt.toLocal8Bit().constData();
1496 else if (res ==
kArg)
1500 cerr <<
"Received '" 1502 <<
"' but unassociated arguments have not been enabled" 1515 cerr <<
"Command line arguments received out of sequence" 1522 if (opt.startsWith(
"-psn_"))
1524 cerr <<
"Ignoring Process Serial Number from command line" 1537 QByteArray
tmp = opt.toLocal8Bit();
1546 cerr <<
"Unhandled option given on command line:" << endl
1547 <<
" " << opt.toLocal8Bit().constData() << endl;
1568 cerr <<
"name: " << argdef->
GetName().toLocal8Bit().constData()
1574 if (!argdef->
Set(opt))
1583 if (!argdef->
Set(opt, val))
1604 cerr <<
"value: " << argdef->
m_stored.toString().toLocal8Bit().constData()
1608 QMap<QString, CommandLineArg*>::const_iterator it;
1612 cerr <<
"Processed option list:" << endl;
1614 (*it)->PrintVerbose();
1618 cerr << endl <<
"Extra argument list:" << endl;
1620 QStringList::const_iterator it2 = slist.begin();
1621 for (; it2 != slist.end(); ++it2)
1622 cerr <<
" " << (*it2).toLocal8Bit().constData() << endl;
1627 cerr << endl <<
"Passthrough string:" << endl;
1628 cerr <<
" " <<
GetPassthrough().toLocal8Bit().constData() << endl;
1637 if (!(*it)->TestLinks())
1639 QString keyword = (*it)->m_usedKeyword;
1640 if (keyword.startsWith(
'-'))
1642 if (keyword.startsWith(
"--"))
1643 keyword.remove(0,2);
1645 keyword.remove(0,1);
1662 cerr <<
"Reconciling links for option interdependencies." << endl;
1664 QMap<QString,CommandLineArg*>::iterator args_it;
1667 QList<CommandLineArg*> links = (*args_it)->m_parents;
1668 QList<CommandLineArg*>::iterator links_it;
1669 for (links_it = links.begin(); links_it != links.end(); ++links_it)
1671 if ((*links_it)->m_type != QVariant::Invalid)
1677 cerr <<
"ERROR: could not reconcile linked argument." << endl
1678 <<
" '" << (*args_it)->m_name.toLocal8Bit().constData()
1679 <<
"' could not find '" 1680 << (*links_it)->m_name.toLocal8Bit().constData()
1682 <<
" Please resolve dependency and recompile." << endl;
1688 cerr << QString(
" Setting %1 as child of %2")
1689 .arg((*args_it)->m_name).arg((*links_it)->m_name)
1690 .toLocal8Bit().constData()
1692 (*args_it)->SetChildOf(
m_namedArgs[(*links_it)->m_name]);
1695 links = (*args_it)->m_children;
1696 for (links_it = links.begin(); links_it != links.end(); ++links_it)
1698 if ((*links_it)->m_type != QVariant::Invalid)
1704 cerr <<
"ERROR: could not reconcile linked argument." << endl
1705 <<
" '" << (*args_it)->m_name.toLocal8Bit().constData()
1706 <<
"' could not find '" 1707 << (*links_it)->m_name.toLocal8Bit().constData()
1709 <<
" Please resolve dependency and recompile." << endl;
1715 cerr << QString(
" Setting %1 as parent of %2")
1716 .arg((*args_it)->m_name).arg((*links_it)->m_name)
1717 .toLocal8Bit().constData()
1719 (*args_it)->SetParentOf(
m_namedArgs[(*links_it)->m_name]);
1722 links = (*args_it)->m_requires;
1723 for (links_it = links.begin(); links_it != links.end(); ++links_it)
1725 if ((*links_it)->m_type != QVariant::Invalid)
1731 cerr <<
"ERROR: could not reconcile linked argument." << endl
1732 <<
" '" << (*args_it)->m_name.toLocal8Bit().constData()
1733 <<
"' could not find '" 1734 << (*links_it)->m_name.toLocal8Bit().constData()
1736 <<
" Please resolve dependency and recompile." << endl;
1742 cerr << QString(
" Setting %1 as requiring %2")
1743 .arg((*args_it)->m_name).arg((*links_it)->m_name)
1744 .toLocal8Bit().constData()
1746 (*args_it)->SetRequires(
m_namedArgs[(*links_it)->m_name]);
1749 QList<CommandLineArg*>::iterator req_it =
1750 (*args_it)->m_requiredby.begin();
1751 while (req_it != (*args_it)->m_requiredby.end())
1753 if ((*req_it)->m_type == QVariant::Invalid)
1758 m_namedArgs[(*req_it)->m_name]->SetRequires(*args_it);
1761 cerr << QString(
" Setting %1 as blocking %2")
1762 .arg((*args_it)->m_name)
1763 .arg((*req_it)->m_name)
1764 .toLocal8Bit().constData()
1770 (*req_it)->DecrRef();
1771 req_it = (*args_it)->m_requiredby.erase(req_it);
1774 QList<CommandLineArg*>::iterator block_it =
1775 (*args_it)->m_blocks.begin();
1776 while (block_it != (*args_it)->m_blocks.end())
1778 if ((*block_it)->m_type != QVariant::Invalid)
1786 (*block_it)->DecrRef();
1787 block_it = (*args_it)->m_blocks.erase(block_it);
1794 cerr << QString(
" Setting %1 as blocking %2")
1795 .arg((*args_it)->m_name).arg((*block_it)->m_name)
1796 .toLocal8Bit().constData()
1799 (*args_it)->SetBlocks(
m_namedArgs[(*block_it)->m_name]);
1839 return toMap(
"_extra");
1858 QMap<QString,QString> smap =
toMap(
"overridesettings");
1862 if (
toBool(
"overridesettingsfile"))
1864 QString filename =
toString(
"overridesettingsfile");
1865 if (!filename.isEmpty())
1868 if (f.open(QIODevice::ReadOnly))
1871 int64_t len = f.readLine(buf,
sizeof(buf) - 1);
1874 if (len >= 1 && buf[len-1]==
'\n')
1877 QStringList tokens = line.split(
"=",
1878 QString::SkipEmptyParts);
1879 if (tokens.size() == 2)
1881 tokens[0].replace(QRegExp(
"^[\"']"),
"");
1882 tokens[0].replace(QRegExp(
"[\"']$"),
"");
1883 tokens[1].replace(QRegExp(
"^[\"']"),
"");
1884 tokens[1].replace(QRegExp(
"[\"']$"),
"");
1885 if (!tokens[0].isEmpty())
1886 smap[tokens[0]] = tokens[1];
1888 len = f.readLine(buf,
sizeof(buf) - 1);
1893 QByteArray
tmp = filename.toLatin1();
1894 cerr <<
"Failed to open the override settings file: '" 1895 <<
tmp.constData() <<
"'" << endl;
1901 smap[
"RunFrontendInWindow"] =
"1";
1902 else if (
toBool(
"notwindowed"))
1903 smap[
"RunFrontendInWindow"] =
"0";
1905 if (
toBool(
"mousecursor"))
1906 smap[
"HideMouseCursor"] =
"0";
1907 else if (
toBool(
"nomousecursor"))
1908 smap[
"HideMouseCursor"] =
"1";
1912 if (!smap.isEmpty())
1915 QMap<QString, QString>::const_iterator it;
1916 for (it = smap.begin(); it != smap.end(); ++it)
1917 vmap[it.key()] = QVariant(it.value());
1919 m_namedArgs[
"overridesettings"]->Set(QVariant(vmap));
1925 cerr <<
"Option Overrides:" << endl;
1926 QMap<QString, QString>::const_iterator it;
1927 for (it = smap.constBegin(); it != smap.constEnd(); ++it)
1928 cerr << QString(
" %1 - %2").arg(it.key(), 30).arg(*it)
1929 .toLocal8Bit().constData() << endl;
1948 if (arg->
m_type == QVariant::Bool)
1974 if (arg->
m_stored.canConvert(QVariant::Int))
1979 if (arg->
m_default.canConvert(QVariant::Int))
1999 if (arg->
m_stored.canConvert(QVariant::UInt))
2004 if (arg->
m_default.canConvert(QVariant::UInt))
2024 if (arg->
m_stored.canConvert(QVariant::LongLong))
2029 if (arg->
m_default.canConvert(QVariant::LongLong))
2049 if (arg->
m_stored.canConvert(QVariant::Double))
2054 if (arg->
m_default.canConvert(QVariant::Double))
2074 if (arg->
m_stored.canConvert(QVariant::Size))
2079 if (arg->
m_default.canConvert(QVariant::Size))
2102 if (arg->
m_stored.canConvert(QVariant::String))
2107 if (arg->
m_default.canConvert(QVariant::String))
2137 if (arg->
m_type == QVariant::String && !sep.isEmpty())
2138 val = varval.toString().split(sep);
2139 else if (varval.canConvert(QVariant::StringList))
2140 val = varval.toStringList();
2150 QMap<QString, QString> val;
2151 QMap<QString, QVariant>
tmp;
2162 if (arg->
m_stored.canConvert(QVariant::Map))
2167 if (arg->
m_default.canConvert(QVariant::Map))
2171 QMap<QString, QVariant>::const_iterator i;
2172 for (i =
tmp.begin(); i !=
tmp.end(); ++i)
2173 val[i.key()] = i.value().toString();
2191 if (arg->
m_stored.canConvert(QVariant::DateTime))
2196 if (arg->
m_default.canConvert(QVariant::DateTime))
2234 QMap<QString,QVariant> vmap;
2254 QVariant::StringList, QStringList());
2262 add(QStringList{
"-h",
"--help",
"--usage"},
2263 "showhelp",
"",
"Display this help printout, or give detailed " 2264 "information of selected option.",
2265 "Displays a list of all commands available for use with " 2266 "this application. If another option is provided as an " 2267 "argument, it will provide detailed information on that " 2275 add(
"--version",
"showversion",
false,
"Display version information.",
2276 "Display informtion about build, including:\n" 2277 " version, branch, protocol, library API, Qt " 2278 "and compiled options.");
2285 add(QStringList{
"-nw",
"--no-windowed"},
2286 "notwindowed",
false,
2287 "Prevent application from running in a window.",
"")
2288 ->SetBlocks(
"windowed")
2291 add(QStringList{
"-w",
"--windowed"},
"windowed",
2292 false,
"Force application to run in a window.",
"")
2293 ->SetGroup(
"User Interface");
2300 add(
"--mouse-cursor",
"mousecursor",
false,
2301 "Force visibility of the mouse cursor.",
"")
2305 add(
"--no-mouse-cursor",
"nomousecursor",
false,
2306 "Force the mouse cursor to be hidden.",
"")
2314 add(QStringList{
"-d",
"--daemon"},
"daemon",
false,
2315 "Fork application into background after startup.",
2316 "Fork application into background, detatching from " 2317 "the local terminal.\nOften used with: " 2318 " --logpath --pidfile --user");
2326 add(QStringList{
"-O",
"--override-setting"},
2327 "overridesettings", QVariant::Map,
2328 "Override a single setting defined by a key=value pair.",
2329 "Override a single setting from the database using " 2330 "options defined as one or more key=value pairs\n" 2331 "Multiple can be defined by multiple uses of the " 2333 add(
"--override-settings-file",
"overridesettingsfile",
"",
2334 "Define a file of key=value pairs to be " 2335 "loaded for setting overrides.",
"");
2342 add(
"--chanid",
"chanid", 0U,
2343 "Specify chanid of recording to operate on.",
"")
2346 add(
"--starttime",
"starttime", QDateTime(),
2347 "Specify start time of recording to operate on.",
"")
2355 add(QStringList{
"-geometry",
"--geometry"},
"geometry",
2356 "",
"Specify window size and position (WxH[+X+Y])",
"")
2357 ->SetGroup(
"User Interface");
2365 add(
"-display",
"display",
"",
"Specify X server to use.",
"")
2374 add(
"--noupnp",
"noupnp",
false,
"Disable use of UPnP.",
"");
2381 const QString &defaultVerbosity, LogLevel_t defaultLogLevel)
2384 ((defaultLogLevel >= LOG_UNKNOWN) || (defaultLogLevel <= LOG_ANY)) ?
2385 LOG_INFO : defaultLogLevel;
2389 add(QStringList{
"-v",
"--verbose"},
"verbose",
2391 "Specify log filtering. Use '-v help' for level info.",
"")
2392 ->SetGroup(
"Logging");
2393 add(
"-V",
"verboseint", 0LL,
"",
2394 "This option is intended for internal use only.\n" 2395 "This option takes an unsigned value corresponding " 2396 "to the bitwise log verbosity operator.")
2398 add(
"--logpath",
"logpath",
"",
2399 "Writes logging messages to a file in the directory logpath with " 2400 "filenames in the format: applicationName.date.pid.log.\n" 2401 "This is typically used in combination with --daemon, and if used " 2402 "in combination with --pidfile, this can be used with log " 2403 "rotators, using the HUP call to inform MythTV to reload the " 2406 add(QStringList{
"-q",
"--quiet"},
"quiet", 0,
2407 "Don't log to the console (-q). Don't log anywhere (-q -q)",
"")
2408 ->SetGroup(
"Logging");
2409 add(
"--loglevel",
"loglevel", logLevelStr,
2411 "Set the logging level. All log messages at lower levels will be " 2413 "In descending order: emerg, alert, crit, err, warning, notice, " 2414 "info, debug\ndefaults to ") + logLevelStr,
"")
2416 add(
"--syslog",
"syslog",
"none",
2417 "Set the syslog logging facility.\nSet to \"none\" to disable, " 2418 "defaults to none.",
"")
2420 #if CONFIG_SYSTEMD_JOURNAL 2421 add(
"--systemd-journal",
"systemd-journal",
"false",
2422 "Use systemd-journal instead of syslog.",
"")
2428 add(
"--nodblog",
"nodblog",
false,
"Disable database logging.",
"")
2430 ->
SetDeprecated(
"this is now the default, see --enable-dblog");
2431 add(
"--enable-dblog",
"enabledblog",
false,
"Enable logging to database.",
"")
2434 add(QStringList{
"-l",
"--logfile"},
2435 "logfile",
"",
"",
"")
2436 ->SetGroup(
"Logging")
2437 ->
SetRemoved(
"This option has been removed as part of " 2438 "rewrite of the logging interface. Please update your init " 2439 "scripts to use --syslog to interface with your system's " 2440 "existing system logging daemon, or --logpath to specify a " 2441 "dirctory for MythTV to write its logs to.",
"0.25");
2448 add(QStringList{
"-p",
"--pidfile"},
"pidfile",
"",
2449 "Write PID of application to filename.",
2450 "Write the PID of the currently running process as a single " 2451 "line to this file. Used for init scripts to know what " 2452 "process to terminate, and with log rotators " 2453 "to send a HUP signal to process to have it re-open files.");
2460 add(QStringList{
"-j",
"--jobid"},
"jobid", 0,
"",
2461 "Intended for internal use only, specify the JobID to match " 2462 "up with in the database for additional information and the " 2463 "ability to update runtime status in the database.");
2470 add(
"--infile",
"infile",
"",
"Input file URI",
"");
2472 add(
"--outfile",
"outfile",
"",
"Output file URI",
"");
2480 pid_t pid = getpid();
2491 LOG(VB_GENERAL, LOG_ERR,
2492 QString(
"%1 is not a directory, disabling logfiles")
2497 logdir = finfo.filePath();
2498 logfile = QCoreApplication::applicationName() +
"." +
2500 QString(
".%1").arg(pid) +
".log";
2513 QString setting =
toString(
"syslog").toLower();
2514 if (setting ==
"none")
2524 QString setting =
toString(
"loglevel");
2525 if (setting.isEmpty())
2529 if (level == LOG_UNKNOWN)
2530 cerr <<
"Unknown log level: " << setting.toLocal8Bit().constData() <<
2546 QVariant val(value);
2553 if (arg->
m_type != value.type())
2577 else if (
toBool(
"verboseint"))
2590 #if CONFIG_SYSTEMD_JOURNAL 2591 bool journal =
toBool(
"systemd-journal");
2599 bool dblog =
toBool(
"enabledblog");
2601 if (level == LOG_UNKNOWN)
2604 LOG(VB_GENERAL, LOG_CRIT,
2605 QString(
"%1 version: %2 [%3] www.mythtv.org")
2606 .arg(QCoreApplication::applicationName())
2608 LOG(VB_GENERAL, LOG_CRIT, QString(
"Qt version: compile: %1, runtime: %2")
2609 .arg(QT_VERSION_STR).arg(qVersion()));
2610 LOG(VB_GENERAL, LOG_NOTICE,
2614 bool propagate = !
logfile.isEmpty();
2631 cerr <<
"Applying settings override" << endl;
2634 if (
override.size())
2636 QMap<QString, QString>::iterator it;
2637 for (it =
override.begin(); it !=
override.end(); ++it)
2639 LOG(VB_GENERAL, LOG_NOTICE,
2640 QString(
"Setting '%1' being forced to '%2'")
2641 .arg(it.key()).arg(*it));
2651 pidfs.open(
pidfile.toLatin1().constData());
2654 cerr <<
"Could not open pid file: " <<
ENO_STR << endl;
2665 if (username.isEmpty())
2669 cerr <<
"--user option is not supported on Windows" << endl;
2672 #if defined(__linux__) || defined(__LINUX__) 2675 int dumpability = prctl(PR_GET_DUMPABLE);
2677 struct passwd *
user_info = getpwnam(username.toLocal8Bit().constData());
2678 const uid_t user_id =
geteuid();
2682 cerr <<
"You must be running as root to use the --user switch." << endl;
2687 LOG(VB_GENERAL, LOG_WARNING,
2688 QString(
"Already running as '%1'").arg(username));
2694 cerr <<
"Error setting home directory." << endl;
2699 cerr <<
"Error setting effective group." << endl;
2704 cerr <<
"Error setting groups." << endl;
2709 cerr <<
"Error setting effective user." << endl;
2712 #if defined(__linux__) || defined(__LINUX__) 2713 if (dumpability && (prctl(PR_SET_DUMPABLE, dumpability) == -1))
2714 LOG(VB_GENERAL, LOG_WARNING,
"Unable to re-enable core file " 2715 "creation. Run without the --user argument to use " 2716 "shell-specified limits.");
2721 cerr << QString(
"Invalid user '%1' specified with --user")
2722 .arg(username).toLocal8Bit().constData() << endl;
2738 if (signal(
SIGPIPE, SIG_IGN) == SIG_ERR)
2739 LOG(VB_GENERAL, LOG_WARNING,
"Unable to ignore SIGPIPE");
2744 cerr <<
"Daemonizing is unavailable in OSX" << endl;
2745 LOG(VB_GENERAL, LOG_WARNING,
"Unable to daemonize");
2750 cerr <<
"Failed to daemonize: " <<
ENO_STR << endl;
2755 QString username =
toString(
"username");
2756 if (!username.isEmpty() && !
setUser(username))
2761 pidfs << getpid() << endl;
int Daemonize(void)
Fork application into background, and detatch from terminal.
QString logLevelGetName(LogLevel_t level)
Map a log level enumerated value back to the name.
virtual void LoadArguments(void)
void allowArgs(bool allow=true)
Specify that parser should allow and collect values provided independent of any keyword.
CommandLineArg * add(QString arg, QString name, bool def, QString help, QString longhelp)
virtual QString GetHelpHeader(void) const
CommandLineArg * SetRequires(QString opt)
Set argument as requiring given option.
void addWindowed(void)
Canned argument definition for –windowed and -no-windowed.
QList< CommandLineArg * > m_parents
QList< CommandLineArg * > m_requires
#define GENERIC_EXIT_OK
Exited with no error.
#define GENERIC_EXIT_DAEMONIZING_ERROR
Error daemonizing or execl.
#define MYTH_BUILD_CONFIG
int GetSyslogFacility(void)
Helper utility for logging interface to return syslog facility.
#define GENERIC_EXIT_PERMISSIONS_ERROR
File permissions error.
QString GetLongHelpString(QString keyword) const
Return string containing extended help text.
void addPIDFile(void)
Canned argument definition for –pidfile.
QMap< QString, QString > GetExtra(void) const
Return map of additional key/value pairs provided on the command line independent of any registered a...
QMap< QString, CommandLineArg * > m_optionedArgs
int syslogGetFacility(QString facility)
Map a syslog facility name back to the enumerated value.
General purpose reference counter.
void PrintHelp(void) const
Print command line option help.
Default UTC, "yyyyMMddhhmmss".
LogLevel_t GetLogLevel(void)
Helper utility for logging interface to filtering level.
bool Set(QString opt)
Set option as provided on command line with no value.
void addMouse(void)
Canned argument definition for –mouse-cursor and –no-mouse-cursor.
#define SYSTEMD_JOURNAL_FACILITY
long long toLongLong(QString key) const
Returns stored QVariant as a long integer, falling to default if not provided.
QString GetHelpString(int off, QString group="", bool force=false) const
Return string containing help text with desired offset.
void allowExtras(bool allow=true)
Specify that parser should allow and collect additional key/value pairs not explicitly defined for pr...
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void addVersion(void)
Canned argument definition for –version.
Definition for a single command line option.
void addLogging(const QString &defaultVerbosity="general", LogLevel_t defaultLogLevel=LOG_INFO)
Canned argument definition for all logging options, including –verbose, –logpath, –quiet,...
void addHelp(void)
Canned argument definition for –help.
bool toBool(QString key) const
Returns stored QVariant as a boolean.
QSize toSize(QString key) const
Returns stored QVariant as a QSize value, falling to default if not provided.
void addDaemon(void)
Canned argument definition for –daemon.
CommandLineArg * SetBlocks(QString opt)
Set argument as incompatible with given option.
bool SetValue(const QString &key, QVariant value)
Set a new stored value for an existing argument definition, or spawn a new definition store value in.
LogLevel_t logLevelGet(QString level)
Map a log level name back to the enumerated value.
int GetKeywordLength(void) const
Return length of full keyword string for use in determining indent of help text.
QMap< QString, QString > toMap(QString key) const
Returns stored QVariant as a QMap, falling to default if not provided.
void logStart(QString logfile, int progress, int quiet, int facility, LogLevel_t level, bool dblog, bool propagate)
Entry point to start logging for the application.
void addUPnP(void)
Canned argument definition for –noupnp.
void CleanupLinks(void)
Clear out references to other arguments in preparation for deletion.
bool setUser(const QString &username)
Drop permissions to the specified user.
void addGeometry(void)
Canned argument definition for –geometry.
bool openPidfile(ofstream &pidfs, const QString &pidfile)
void addInFile(bool addOutFile=false)
Canned argument definition for –infile and –outfile.
void ApplySettingsOverride(void)
Apply all overrides to the global context.
QMap< QString, CommandLineArg * > m_namedArgs
QStringList GetArgs(void) const
Return list of additional values provided on the command line independent of any keyword.
CommandLineArg * SetParent(QString opt)
Set argument as child of given parent.
virtual int IncrRef(void)
Increments reference count.
CommandLineArg * SetParentOf(QString opt)
Set argument as parent of given child.
void PrintDeprecatedWarning(QString &keyword) const
Internal use.
void OverrideSettingForSession(const QString &key, const QString &value)
QString GetPassthrough(void) const
Return any text supplied on the command line after a bare '–'.
def user_info(user, format="xml")
static void AllowOneOf(QList< CommandLineArg * > args)
Mark a list of arguments as mutually exclusive.
CommandLineArg * SetChildOf(QString opt)
Set argument as child of given parent.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
MythCommandLineParser(QString)
Default constructor for MythCommandLineArg class.
QString GetName(void) const
QString toString(QString key) const
Returns stored QVariant as a QString, falling to default if not provided.
CommandLineArg * SetRequiredChild(QString opt)
Set argument as parent of given child and mark as required.
QList< CommandLineArg * > m_requiredby
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
QDateTime toDateTime(QString key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
int verboseArgParse(QString arg)
Parse the –verbose commandline argument and set the verbose level.
void addJob(void)
Canned argument definition for –jobid.
CommandLineArg * SetRemoved(QString remstr="", QString remver="")
Set option as removed.
double toDouble(QString key) const
Returns stored QVariant as double floating point value, falling to default if not provided.
bool ReconcileLinks(void)
Replace dummy arguments used to define interdependency with pointers to their real counterparts.
#define LOG(_MASK_, _LEVEL_, _STRING_)
QString GetHelpString(void) const
Generate command line option help text.
bool TestLinks(void) const
Test all related arguments to make sure specified requirements are fulfilled.
QList< CommandLineArg * > m_blocks
void wrapList(QStringList &list, int width)
void PrintRemovedWarning(QString &keyword) const
Internal use.
QMap< QString, QString > GetSettingsOverride(void)
Return map of key/value pairs provided to override database options.
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
int GetTermWidth(void)
returns terminal width, or 79 on error
void PrintVerbose(void) const
Internal use.
CommandLineArg * SetGroup(QString group)
QString GetPreferredKeyword(void) const
Return the longest keyword for the argument.
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
void addDisplay(void)
Canned argument definition for -display.
CommandLineArg * SetRequiredChildOf(QString opt)
Set argument as child required by given parent.
CommandLineArg * SetChild(QString opt)
Set argument as parent of given child.
int toInt(QString key) const
Returns stored QVariant as an integer, falling to default if not provided.
int ConfigureLogging(QString mask="general", unsigned int progress=0)
Read in logging options and initialize the logging interface.
QList< CommandLineArg * > m_children
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
const char * NamedOptType(int type)
QString GetLogFilePath(void)
Helper utility for logging interface to pull path from –logpath.
QVariant operator[](const QString &name)
Returned stored QVariant for given argument, or default value if not used.
void AddKeyword(QString keyword)
void addSettingsOverride(void)
Canned argument definition for –override-setting and –override-settings-file.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QStringList toStringList(QString key, QString sep="") const
Returns stored QVariant as a QStringList, falling to default if not provided.
#define MYTH_SOURCE_VERSION
CommandLineArg * SetDeprecated(QString depstr="")
Set option as deprecated.
void PrintVersion(void) const
Print application version information.
void allowPassthrough(bool allow=true)
Specify that parser should allow a bare '–', and collect all subsequent text as a QString.
void addRecording(void)
Canned argument definition for –chanid and –starttime.
QString GetKeywordString(void) const
Return string containing all possible keyword triggers for this argument.
uint toUInt(QString key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
int getOpt(int argc, const char *const *argv, int &argpos, QString &opt, QByteArray &val)
Internal use.
CommandLineArg(QString name, QVariant::Type type, QVariant def, QString help, QString longhelp)
Default constructor for CommandLineArg class.
void Convert(void)
Convert stored string value from QByteArray to QString.