summaryrefslogtreecommitdiffstats
path: root/kcron/cttask.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcron/cttask.cpp')
-rw-r--r--kcron/cttask.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/kcron/cttask.cpp b/kcron/cttask.cpp
new file mode 100644
index 0000000..1b7b299
--- /dev/null
+++ b/kcron/cttask.cpp
@@ -0,0 +1,361 @@
+/***************************************************************************
+ * CT Task Implementation *
+ * -------------------------------------------------------------------- *
+ * Copyright (C) 1999, Gary Meyer <gary@meyer.net> *
+ * -------------------------------------------------------------------- *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes.
+// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99
+
+#include "cttask.h"
+
+#include "cti18n.h"
+#include <time.h> // tm, strftime()
+
+CTTask::CTTask(string tokStr, string _comment, bool _syscron) :
+ syscron(_syscron)
+{
+ if (tokStr.substr(0,2) == "#\\")
+ {
+ tokStr = tokStr.substr(2,tokStr.length() - 2);
+ enabled = false;
+ }
+ else if (tokStr.substr(0,1) == "#")
+ {
+ tokStr = tokStr.substr(1,tokStr.length() - 1);
+ enabled = false;
+ }
+ else
+ enabled = true;
+
+ if (tokStr.substr(0,1) == "-")
+ {
+ tokStr = tokStr.substr(1,tokStr.length() - 1);
+ silent = true;
+ }
+ else
+ {
+ silent = false;
+ }
+
+ if (tokStr.substr(0,1) == "@")
+ {
+ if (tokStr.substr(1,6) == "reboot")
+ {
+ // Dunno what to do with this...
+ tokStr = "0 0 1 1 *"+tokStr.substr(7,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,6) == "yearly")
+ {
+ tokStr = "0 0 1 1 *"+tokStr.substr(7,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,8) == "annually")
+ {
+ tokStr = "0 0 1 1 *"+tokStr.substr(9,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,7) == "monthly")
+ {
+ tokStr = "0 0 1 * *"+tokStr.substr(8,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,6) == "weekly")
+ {
+ tokStr = "0 0 * * 0"+tokStr.substr(7,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,5) == "daily")
+ {
+ tokStr = "0 0 * * *"+tokStr.substr(6,tokStr.length()-1);
+ }
+ else if (tokStr.substr(1,6) == "hourly")
+ {
+ tokStr = "0 * * * *"+tokStr.substr(7,tokStr.length()-1);
+ }
+ }
+
+ int spacepos(tokStr.find_first_of(" \t"));
+ minute.initialize(tokStr.substr(0,spacepos));
+
+ while(isspace(tokStr[spacepos+1])) spacepos++;
+ tokStr = tokStr.substr(spacepos+1,tokStr.length()-1);
+ spacepos = tokStr.find_first_of(" \t");
+ hour.initialize(tokStr.substr(0,spacepos));
+
+ while(isspace(tokStr[spacepos+1])) spacepos++;
+ tokStr = tokStr.substr(spacepos+1,tokStr.length()-1);
+ spacepos = tokStr.find_first_of(" \t");
+ dayOfMonth.initialize(tokStr.substr(0,spacepos));
+
+ while(isspace(tokStr[spacepos+1])) spacepos++;
+ tokStr = tokStr.substr(spacepos+1,tokStr.length()-1);
+ spacepos = tokStr.find_first_of(" \t");
+ month.initialize(tokStr.substr(0,spacepos));
+
+ while(isspace(tokStr[spacepos+1])) spacepos++;
+ tokStr = tokStr.substr(spacepos+1,tokStr.length()-1);
+ spacepos = tokStr.find_first_of(" \t");
+ dayOfWeek.initialize(tokStr.substr(0,spacepos));
+
+ if (syscron)
+ {
+ while(isspace(tokStr[spacepos+1])) spacepos++;
+ tokStr = tokStr.substr(spacepos+1,tokStr.length()-1);
+ spacepos = tokStr.find_first_of(" \t");
+ user = tokStr.substr(0,spacepos);
+ }
+ else
+ user = string("");
+
+ command = tokStr.substr(spacepos+1,tokStr.length()-1);
+ // remove leading whitespace
+ while (command.find_first_of(" \t") == 0)
+ command = command.substr(1,command.length()-1);
+ comment = _comment;
+
+ initialUser = user;
+ initialCommand = command;
+ initialComment = comment;
+ initialEnabled = enabled;
+ initialSilent = silent;
+}
+
+CTTask::CTTask(const CTTask &source) :
+ month(source.month),
+ dayOfMonth(source.dayOfMonth),
+ dayOfWeek(source.dayOfWeek),
+ hour(source.hour),
+ minute(source.minute),
+ user(source.user),
+ command(source.command),
+ comment(source.comment),
+ enabled(source.enabled),
+ silent(source.silent),
+ initialUser(""),
+ initialCommand(""),
+ initialComment(""),
+ initialEnabled(true),
+ initialSilent(false)
+{
+}
+
+void CTTask::operator = (const CTTask& source)
+{
+ month = source.month;
+ dayOfMonth = source.dayOfMonth;
+ dayOfWeek = source.dayOfWeek;
+ hour = source.hour;
+ minute = source.minute;
+ user = source.user;
+ command = source.command;
+ comment = source.comment;
+ enabled = source.enabled;
+ silent = source.silent;
+ initialUser = "";
+ initialCommand = "";
+ initialComment = "";
+ initialEnabled = true;
+ initialSilent = false;
+ return;
+}
+
+ostream& operator << (ostream& outputStream, const CTTask& task)
+{
+// if (task.comment != string(""))
+ outputStream << "# " << task.comment << "\n";
+
+ if (!task.enabled)
+ outputStream << "#\\";
+
+ if (task.silent)
+ outputStream << "-";
+
+ outputStream << task.minute << " ";
+ outputStream << task.hour << " ";
+ outputStream << task.dayOfMonth << " ";
+ outputStream << task.month << " ";
+ outputStream << task.dayOfWeek << "\t";
+
+ if (task.user != string(""))
+ outputStream << task.user << "\t";
+
+ outputStream << task.command << "\n";
+
+ return outputStream;
+}
+
+void CTTask::apply()
+{
+ month.apply();
+ dayOfMonth.apply();
+ dayOfWeek.apply();
+ hour.apply();
+ minute.apply();
+ initialUser = user;
+ initialCommand = command;
+ initialComment = comment;
+ initialEnabled = enabled;
+ initialSilent = silent;
+}
+
+void CTTask::cancel()
+{
+ month.cancel();
+ dayOfMonth.cancel();
+ dayOfWeek.cancel();
+ hour.cancel();
+ minute.cancel();
+ user = initialUser;
+ command = initialCommand;
+ comment = initialComment;
+ enabled = initialEnabled;
+ silent = initialSilent;
+}
+
+bool CTTask::dirty() const
+{
+ return (month.dirty() || dayOfMonth.dirty() || dayOfWeek.dirty() ||
+ hour.dirty() || minute.dirty() || (user != initialUser) ||
+ (command != initialCommand) || (comment != initialComment) ||
+ (enabled != initialEnabled) || (silent != initialSilent));
+}
+
+string CTTask::describe() const
+{
+
+ // Of the whole program, this method is probably the trickiest.
+ //
+ // This method creates the natural language description, such as
+ // "At 1:00am, every Sun".
+ //
+ // First, I declare some strings for holding what can be internationalized.
+ // Note the tokens such as "MONTHS". Translators should reuse these
+ // tokens in their translations. See README.translators for more
+ // information.
+ //
+ // Second, I get the descriptions from the component parts such as
+ // days of the month.
+ //
+ // Third, I get hour/minute time combinations. Although a little bit
+ // awkward, I use the tm struct and strftime from <time.h>. This
+ // way this code is portable across all Unixes.
+ //
+ // Fourth, I know that "every day of the week" and "every day of the
+ // month" simply makes "every day".
+ //
+ // Fifth and finally I do tag substitution to create the natural language
+ // description.
+
+ string tmFormat((const char *)i18n("%H:%M").local8Bit());
+ string DOMFormat((const char *)i18n("Please translator, read the README.translators file in kcron's source code","DAYS_OF_MONTH of MONTHS").local8Bit());
+ string DOWFormat((const char *)i18n("Really, read that file","every DAYS_OF_WEEK").local8Bit());
+ string dateFormat((const char *)i18n("DOM_FORMAT as well as DOW_FORMAT").local8Bit());
+ string timeFormat((const char *)i18n("At TIME").local8Bit());
+ string format((const char *)i18n("TIME_FORMAT, DATE_FORMAT").local8Bit());
+
+ // Get natural language description of day of month,
+ // month name, and day of week.
+
+ string DOMDesc(dayOfMonth.describe());
+ string monthDesc(month.describe());
+ string DOWDesc(dayOfWeek.describe());
+
+ // Create time description.
+
+ int total(minute.count()*hour.count());
+
+ string timeDesc("");
+ int count(0);
+
+ for (int h = 0; h <= 23; h++)
+ if (hour.get(h))
+ for (int m = 0; m <= 59; m++)
+ if (minute.get(m))
+ {
+ tm time;
+ time.tm_sec = 0;
+ time.tm_min = m;
+ time.tm_hour = h;
+ time.tm_mday = 0;
+ time.tm_mon = 0;
+ time.tm_year = 0;
+ time.tm_wday = 0;
+ time.tm_yday = 0;
+ time.tm_isdst= 0;
+
+ char tmp[12];
+ strftime(tmp, 12, tmFormat.c_str(), &time);
+ string tmpStr = tmp;
+
+ // remove leading space
+ if (tmpStr.substr(0,1) == " ")
+ tmpStr = tmpStr.substr(1,tmpStr.length()-1);
+
+ timeDesc += tmpStr;
+ count++;
+ switch (total - count)
+ {
+ case 0: break;
+ case 1: if (total > 2)
+ timeDesc += (const char *)i18n(", and ").local8Bit();
+ else
+ timeDesc += (const char *)i18n(" and ").local8Bit();
+ break;
+ default: timeDesc += (const char*)i18n(", ").local8Bit();
+ }
+ }
+
+ // "* * *" means truly every day.
+ // Note: Languages may use different phrases to indicate
+ // every day of month versus every day of week.
+
+ if ((dayOfMonth.count() == 31) &&
+ (dayOfWeek.count() == 7))
+ dateFormat = (const char *)i18n("every day ").local8Bit();
+ else
+ {
+ // Day of month not specified, so use day of week.
+ if (dayOfMonth.count() == 31)
+ dateFormat = "DOW_FORMAT";
+ // Day of week not specified, so use day of month.
+ if (dayOfWeek.count() == 7)
+ dateFormat = "DOM_FORMAT";
+ }
+
+ // Replace tags to build natural language description.
+
+ int pos(0);
+
+ if ((pos = DOMFormat.find("DAYS_OF_MONTH")) > -1)
+ DOMFormat.replace(pos,13,DOMDesc);
+
+ if ((pos = DOMFormat.find("MONTHS")) > -1)
+ DOMFormat.replace(pos,6,monthDesc);
+
+ if ((pos = DOWFormat.find("DAYS_OF_WEEK")) > -1)
+ DOWFormat.replace(pos,12,DOWDesc);
+
+ if ((pos = dateFormat.find("DOM_FORMAT")) > -1)
+ dateFormat.replace(pos,10,DOMFormat);
+
+ if ((pos = dateFormat.find("DOW_FORMAT")) > -1)
+ dateFormat.replace(pos,10,DOWFormat);
+
+ if ((pos = timeFormat.find("TIME")) > -1)
+ timeFormat.replace(pos,4,timeDesc);
+
+ if ((pos = format.find("DATE_FORMAT")) > -1)
+ format.replace(pos,11,dateFormat);
+
+ if ((pos = format.find("TIME_FORMAT")) > -1)
+ format.replace(pos,11,timeFormat);
+
+ return format;
+}
+
+bool CTTask::system() const
+{
+ return syscron;
+}