+
+void encode_session_key(char *encode, char *session, char *key, int maxlen)
+{
+ int i;
+ for (i=0; (i < maxlen-1) && session[i]; i++) {
+ if (session[i] == '-') {
+ encode[i] = '-';
+ } else {
+ encode[i] = ((session[i] - 'A' + key[i]) & 0xF) + 'A';
+ }
+ }
+ encode[i] = 0;
+ Dmsg3(000, "Session=%s key=%s encode=%s\n", session, key, encode);
+}
+
+void decode_session_key(char *decode, char *session, char *key, int maxlen)
+{
+ int i, x;
+
+ for (i=0; (i < maxlen-1) && session[i]; i++) {
+ if (session[i] == '-') {
+ decode[i] = '-';
+ } else {
+ x = (session[i] - 'A' - key[i]) & 0xF;
+ if (x < 0) {
+ x += 16;
+ }
+ decode[i] = x + 'A';
+ }
+ }
+ decode[i] = 0;
+ Dmsg3(000, "Session=%s key=%s decode=%s\n", session, key, decode);
+}
+
+
+
+/*
+ * Edit job codes into main command line
+ * %% = %
+ * %c = Client's name
+ * %d = Director's name
+ * %e = Job Exit code
+ * %i = JobId
+ * %j = Unique Job id
+ * %l = job level
+ * %n = Unadorned Job name
+ * %s = Since time
+ * %t = Job type (Backup, ...)
+ * %r = Recipients
+ * %v = Volume name
+ * %b = Job Bytes
+ * %f = Job Files
+ *
+ * omsg = edited output message
+ * imsg = input string containing edit codes (%x)
+ * to = recepients list
+ *
+ */
+POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to, job_code_callback_t callback)
+{
+ char *p, *q;
+ const char *str;
+ char add[50];
+ char name[MAX_NAME_LENGTH];
+ int i;
+
+ *omsg = 0;
+ Dmsg1(200, "edit_job_codes: %s\n", imsg);
+ for (p=imsg; *p; p++) {
+ if (*p == '%') {
+ switch (*++p) {
+ case '%':
+ str = "%";
+ break;
+ case 'c':
+ if (jcr) {
+ str = jcr->client_name;
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'd':
+ str = my_name; /* Director's name */
+ break;
+ case 'e':
+ if (jcr) {
+ str = job_status_to_str(jcr->JobStatus);
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'i':
+ if (jcr) {
+ bsnprintf(add, sizeof(add), "%d", jcr->JobId);
+ str = add;
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'j': /* Job name */
+ if (jcr) {
+ str = jcr->Job;
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'l':
+ if (jcr) {
+ str = job_level_to_str(jcr->getJobLevel());
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'n':
+ if (jcr) {
+ bstrncpy(name, jcr->Job, sizeof(name));
+ /* There are three periods after the Job name */
+ for (i=0; i<3; i++) {
+ if ((q=strrchr(name, '.')) != NULL) {
+ *q = 0;
+ }
+ }
+ str = name;
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'r':
+ str = to;
+ break;
+ case 's': /* since time */
+ if (jcr && jcr->stime) {
+ str = jcr->stime;
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'f': /* Job Files */
+ str = edit_uint64(jcr->JobFiles, add);
+ break;
+ case 'b': /* Job Bytes */
+ str = edit_uint64(jcr->JobBytes, add);
+ break;
+ case 't':
+ if (jcr) {
+ str = job_type_to_str(jcr->getJobType());
+ } else {
+ str = _("*none*");
+ }
+ break;
+ case 'v':
+ if (jcr) {
+ if (jcr->VolumeName && jcr->VolumeName[0]) {
+ str = jcr->VolumeName;
+ } else {
+ str = "";
+ }
+ } else {
+ str = _("*none*");
+ }
+ break;
+ default:
+ str = NULL;
+ if (callback != NULL) {
+ str = callback(jcr, p);
+ }
+
+ if (!str) {
+ add[0] = '%';
+ add[1] = *p;
+ add[2] = 0;
+ str = add;
+ }
+ break;
+ }
+ } else {
+ add[0] = *p;
+ add[1] = 0;
+ str = add;
+ }
+ Dmsg1(1200, "add_str %s\n", str);
+ pm_strcat(&omsg, str);
+ Dmsg1(1200, "omsg=%s\n", omsg);
+ }
+ return omsg;
+}
+
+void set_working_directory(char *wd)
+{
+ struct stat stat_buf;
+
+ if (wd == NULL) {
+ Emsg0(M_ERROR_TERM, 0, _("Working directory not defined. Cannot continue.\n"));
+ }
+ if (stat(wd, &stat_buf) != 0) {
+ Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" not found. Cannot continue.\n"),
+ wd);
+ }
+ if (!S_ISDIR(stat_buf.st_mode)) {
+ Emsg1(M_ERROR_TERM, 0, _("Working Directory: \"%s\" is not a directory. Cannot continue.\n"),
+ wd);
+ }
+ working_directory = wd; /* set global */
+}
+
+const char *last_path_separator(const char *str)
+{
+ if (*str != '\0') {
+ for (const char *p = &str[strlen(str) - 1]; p >= str; p--) {
+ if (IsPathSeparator(*p)) {
+ return p;
+ }
+ }
+ }
+ return NULL;
+}