---
 rules/99-systemd.rules.in |    2 
 src/core/manager.c        |   24 ++++++++--
 src/shared/util.c         |  101 ++++++++++++++++++++++++++++++++++++++++++++--
 src/shared/util.h         |    1 
 4 files changed, 118 insertions(+), 10 deletions(-)


--- systemd-208/rules/99-systemd.rules.in
+++ systemd-208/rules/99-systemd.rules.in	2014-02-05 10:34:17.346235540 +0000
@@ -7,7 +7,7 @@
 
 ACTION=="remove", GOTO="systemd_end"
 
-SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*", TAG+="systemd"
+SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty*", TAG+="systemd"
 
 KERNEL=="vport*", TAG+="systemd"
 
--- systemd-210/src/core/manager.c
+++ systemd-210/src/core/manager.c	2014-04-30 10:51:43.398735332 +0000
@@ -110,7 +110,7 @@ static int manager_watch_jobs_in_progres
 
 #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
 
-static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
+static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos, bool ansi_console) {
         char *p = buffer;
 
         assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
@@ -119,12 +119,14 @@ static void draw_cylon(char buffer[], si
         if (pos > 1) {
                 if (pos > 2)
                         p = mempset(p, ' ', pos-2);
-                p = stpcpy(p, ANSI_RED_ON);
+                if (ansi_console)
+                        p = stpcpy(p, ANSI_RED_ON);
                 *p++ = '*';
         }
 
         if (pos > 0 && pos <= width) {
-                p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
+                if (ansi_console)
+                        p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
                 *p++ = '*';
         }
 
@@ -135,7 +137,8 @@ static void draw_cylon(char buffer[], si
                 *p++ = '*';
                 if (pos < width-1)
                         p = mempset(p, ' ', width-1-pos);
-                strcpy(p, ANSI_HIGHLIGHT_OFF);
+                if (ansi_console)
+                        strcpy(p, ANSI_HIGHLIGHT_OFF);
         }
 }
 
@@ -150,6 +153,7 @@ void manager_flip_auto_status(Manager *m
 }
 
 static void manager_print_jobs_in_progress(Manager *m) {
+        static int is_ansi_console = -1;
         _cleanup_free_ char *job_of_n = NULL;
         Iterator i;
         Job *j;
@@ -174,10 +178,20 @@ static void manager_print_jobs_in_progre
         assert(counter == print_nr + 1);
         assert(j);
 
+        if (_unlikely_(is_ansi_console < 0)) {
+                int fd = open_terminal("/dev/console", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (fd < 0)
+                        is_ansi_console = 0;
+                else {
+                        is_ansi_console = (int)ansi_console(fd);
+                        close(fd);
+                }
+        }
+
         cylon_pos = m->jobs_in_progress_iteration % 14;
         if (cylon_pos >= 8)
                 cylon_pos = 14 - cylon_pos;
-        draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
+        draw_cylon(cylon, sizeof(cylon), 6, cylon_pos, (bool)is_ansi_console);
 
         m->jobs_in_progress_iteration++;
 
--- systemd-210/src/shared/util.c
+++ systemd-210/src/shared/util.c	2014-04-30 10:39:17.154736438 +0000
@@ -2886,6 +2886,7 @@ int status_vprintf(const char *status, b
         struct iovec iovec[6] = {};
         int n = 0;
         static bool prev_ephemeral;
+        static int is_ansi_console = -1;
 
         assert(format);
 
@@ -2899,6 +2900,41 @@ int status_vprintf(const char *status, b
         if (fd < 0)
                 return fd;
 
+        if (_unlikely_(is_ansi_console < 0))
+                is_ansi_console = (int)ansi_console(fd);
+
+        if (status && !is_ansi_console) {
+                const char *esc, *ptr;
+                esc = strchr(status, 0x1B);
+                if (esc && (ptr = strpbrk(esc, "SOFDTI*"))) {
+                        switch(*ptr) {
+                        case 'S':
+                                status = " SKIP ";
+                                break;
+                        case 'O':
+                                status = "  OK  ";
+                                break;
+                        case 'F':
+                                status = "FAILED";
+                                break;
+                        case 'D':
+                                status = "DEPEND";
+                                break;
+                        case 'T':
+                                status = " TIME ";
+                                break;
+                        case 'I':
+                                status = " INFO ";
+                                break;
+                        case '*':
+                                status = " BUSY ";
+                                break;
+                        default:
+                                break;
+                        }
+                }
+        }
+
         if (ellipse) {
                 char *e;
                 size_t emax, sl;
@@ -2921,8 +2957,12 @@ int status_vprintf(const char *status, b
                 }
         }
 
-        if (prev_ephemeral)
-                IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
+        if (prev_ephemeral) {
+                if (is_ansi_console)
+                        IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
+                else
+                        IOVEC_SET_STRING(iovec[n++], "\r");
+        }
         prev_ephemeral = ephemeral;
 
         if (status) {
@@ -3169,12 +3209,47 @@ void columns_lines_cache_reset(int signu
 bool on_tty(void) {
         static int cached_on_tty = -1;
 
-        if (_unlikely_(cached_on_tty < 0))
+        if (_unlikely_(cached_on_tty < 0)) {
                 cached_on_tty = isatty(STDOUT_FILENO) > 0;
+#if defined (__s390__) || defined (__s390x__)
+                if (cached_on_tty) {
+                        const char *e = getenv("TERM");
+                        if (!e)
+                                return cached_on_tty;
+                        if (streq(e, "dumb") || strneq(e, "ibm3", 4)) {
+                                char *mode = NULL;
+                                int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", &mode, NULL);
+                                if (r < 0 || !mode || !streq(mode, "3270"))
+                                        cached_on_tty = 0;
+                        }
+                }
+#endif
+        }
 
         return cached_on_tty;
 }
 
+bool ansi_console(int fd) {
+        static int cached_ansi_console = -1;
+
+        if (_unlikely_(cached_ansi_console < 0)) {
+                cached_ansi_console = isatty(fd) > 0;
+#if defined (__s390__) || defined (__s390x__)
+                if (cached_ansi_console) {
+                        const char *e = getenv("TERM");
+                        if (e && (streq(e, "dumb") || strneq(e, "ibm3", 4))) {
+                                char *mode = NULL;
+                                int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", &mode, NULL);
+                                if (r < 0 || !mode || !streq(mode, "3270"))
+                                        cached_ansi_console = 0;
+                        }
+                }
+#endif
+        }
+
+        return cached_ansi_console;
+}
+
 int running_in_chroot(void) {
         struct stat a = {}, b = {};
 
@@ -3630,7 +3705,25 @@ bool tty_is_vc_resolve(const char *tty)
 const char *default_term_for_tty(const char *tty) {
         assert(tty);
 
-        return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
+        if (tty_is_vc_resolve(tty))
+                return "TERM=linux";
+
+        if (startswith(tty, "/dev/"))
+                tty += 5;
+
+#if defined (__s390__) || defined (__s390x__)
+        if (streq(tty, "ttyS0")) {
+                char *mode = NULL;
+                int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", &mode, NULL);
+                if (r < 0 || !mode || !streq(mode, "3270"))
+                        return "TERM=dumb";
+                if (streq(mode, "3270"))
+                        return "TERM=ibm327x";
+        }
+        if (streq(tty, "ttyS1"))
+                return "TERM=vt220";
+#endif
+        return "TERM=vt102";
 }
 
 bool dirent_is_file(const struct dirent *de) {
--- systemd-210/src/shared/util.h
+++ systemd-210/src/shared/util.h	2014-04-30 10:24:51.134235665 +0000
@@ -418,6 +418,7 @@ unsigned lines(void);
 void columns_lines_cache_reset(int _unused_ signum);
 
 bool on_tty(void);
+bool ansi_console(int fd);
 
 static inline const char *ansi_highlight(void) {
         return on_tty() ? ANSI_HIGHLIGHT_ON : "";
