From owner-svn-src-head@freebsd.org Fri Aug 23 03:01:32 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 15031D8790; Fri, 23 Aug 2019 03:01:32 +0000 (UTC) (envelope-from cse.cem@gmail.com) Received: from mail-io1-f47.google.com (mail-io1-f47.google.com [209.85.166.47]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46F5lH6nfZz4D8J; Fri, 23 Aug 2019 03:01:31 +0000 (UTC) (envelope-from cse.cem@gmail.com) Received: by mail-io1-f47.google.com with SMTP id t3so16629669ioj.12; Thu, 22 Aug 2019 20:01:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc; bh=Zs6o53r0D1JgdCUZjbl6pbzz+ScDhDPsptj3QBl0yD4=; b=TQPk24oJRoxZNzwCczYiRWuQt6rPrRGeM0i+QnEeIKWrl9O+7gdBo/zIMEFZQf6rv8 qoG4VLhA6hk3ZBOdCJWSs45W9MuJn08B/74iqqxqOTUQF/8Au5H6NOB1xy9wfqq6cOq8 PXpwbZCjP+WipHWkqTI2Xu0G/cSB9wMudALTVhLA1IZPqXrRtTq8xSm6DLL9tTnSX2qg d4bQEyQvJSApJhWA6crSFQbQdtzrgD5ZyW9LJ5sc7XavWEnW67VcPNZksNbdG7FSUiuq EbxR/KMvFNScQRrnDdrA8m0i6Ap0MZTrhHd/exbpovE+JF216ZzJQdUBEH3BB09zm7JA +otA== X-Gm-Message-State: APjAAAUAzm0623M2Z4WExsqmcn60SkZm2rPCJRZYzc5wiOlLd8EeGYdn FnelNrMG3pKz3pPR51XowF8HJuvq X-Google-Smtp-Source: APXvYqwCUhrB/vCnkFmNOCP0Onm41O7U8nu1xqO2sjhhqtoPPNQjwQ8KAetVU1lgunkC3emo7nR5Pw== X-Received: by 2002:a6b:761a:: with SMTP id g26mr3875763iom.71.1566529290235; Thu, 22 Aug 2019 20:01:30 -0700 (PDT) Received: from mail-io1-f41.google.com (mail-io1-f41.google.com. [209.85.166.41]) by smtp.gmail.com with ESMTPSA id q3sm1278938ios.70.2019.08.22.20.01.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 22 Aug 2019 20:01:29 -0700 (PDT) Received: by mail-io1-f41.google.com with SMTP id j5so16682993ioj.8; Thu, 22 Aug 2019 20:01:27 -0700 (PDT) X-Received: by 2002:a02:3745:: with SMTP id r66mr2855244jar.23.1566529287696; Thu, 22 Aug 2019 20:01:27 -0700 (PDT) MIME-Version: 1.0 References: <201908230125.x7N1PdTN070890@repo.freebsd.org> In-Reply-To: <201908230125.x7N1PdTN070890@repo.freebsd.org> Reply-To: cem@freebsd.org From: Conrad Meyer Date: Thu, 22 Aug 2019 20:01:16 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: svn commit: r351413 - head/usr.bin/last To: Eugene Grosbein Cc: src-committers , svn-src-all , svn-src-head Content-Type: text/plain; charset="UTF-8" X-Rspamd-Queue-Id: 46F5lH6nfZz4D8J X-Spamd-Bar: ------ Authentication-Results: mx1.freebsd.org; none X-Spamd-Result: default: False [-6.98 / 15.00]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.98)[-0.977,0]; REPLY(-4.00)[]; TAGGED_FROM(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Aug 2019 03:01:32 -0000 Hi Eugene, Should this be done more generally? Last time I looked it seemed like libxo was completely locale-unaware and just assumed all input was UTF-8. It might make more sense to have libxo take locale into account when formatting %s strings. Best, Conrad On Thu, Aug 22, 2019 at 6:25 PM Eugene Grosbein wrote: > > Author: eugen > Date: Fri Aug 23 01:25:38 2019 > New Revision: 351413 > URL: https://svnweb.freebsd.org/changeset/base/351413 > > Log: > last(1): unbreak for 8-bit locales > > Ouput format of last(1) is broken for non UTF-8 locales > since it got libxo(3) support. It uses strftime(3) that produces > non UTF-8 strings passed to xo_emit(3) with wrong %s format - > it should be %hs in this case, so xo_emit(3) produces empty output. > > This change is basically no-op when locale is of UTF-8 type, > f.e. en_GB.UTF-8 or ru_RU.UTF-8 or sr_RS.UTF-8@latin. > It fixes output for other locales. > > MFC after: 2 weeks > > Modified: > head/usr.bin/last/last.c > > Modified: head/usr.bin/last/last.c > ============================================================================== > --- head/usr.bin/last/last.c Fri Aug 23 01:16:12 2019 (r351412) > +++ head/usr.bin/last/last.c Fri Aug 23 01:25:38 2019 (r351413) > @@ -93,6 +93,7 @@ static time_t currentout; /* current logout value */ > static long maxrec; /* records to display */ > static const char *file = NULL; /* utx.log file */ > static int sflag = 0; /* show delta in seconds */ > +static int utf8flag; /* current locale is UTF-8 */ > static int width = 5; /* show seconds in delta */ > static int yflag; /* show year */ > static int d_first; > @@ -103,6 +104,7 @@ static time_t snaptime; /* if != 0, we will only > */ > > static void addarg(int, char *); > +static const char *ctf(const char *); > static time_t dateconv(char *); > static void doentry(struct utmpx *); > static void hostconv(char *); > @@ -112,6 +114,31 @@ static int want(struct utmpx *); > static void usage(void); > static void wtmp(void); > > +static const char* > +ctf(const char *fmt) { > + static char buf[31]; > + const char *src, *end; > + char *dst; > + > + if (utf8flag) > + return (fmt); > + > + end = buf + sizeof(buf); > + for (src = fmt, dst = buf; dst < end; *dst++ = *src++) { > + if (*src == '\0') { > + *dst = '\0'; > + break; > + } else if (*src == '%' && *(src+1) == 's') { > + *dst++ = '%'; > + *dst++ = 'h'; > + *dst++ = 's'; > + strlcpy(dst, src+2, end - dst); > + return (buf); > + } > + } > + return (buf); > +} > + > static void > usage(void) > { > @@ -130,6 +157,9 @@ main(int argc, char *argv[]) > (void) setlocale(LC_TIME, ""); > d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); > > + (void) setlocale(LC_CTYPE, ""); > + utf8flag = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0); > + > argc = xo_parse_args(argc, argv); > if (argc < 0) > exit(1); > @@ -262,7 +292,7 @@ wtmp(void) > (void) strftime(ct, sizeof(ct), "%+", tm); > xo_emit("\n{:utxdb/%s}", (file == NULL) ? "utx.log" : file); > xo_attr("seconds", "%lu", (unsigned long) t); > - xo_emit(" begins {:begins/%s}\n", ct); > + xo_emit(ctf(" begins {:begins/%s}\n"), ct); > xo_close_container("last-information"); > } > > @@ -379,7 +409,7 @@ printentry(struct utmpx *bp, struct idtab *tt) > break; > } > xo_attr("seconds", "%lu", (unsigned long)t); > - xo_emit(" {:login-time/%s%c/%s}", ct, tt == NULL ? '\n' : ' '); > + xo_emit(ctf(" {:login-time/%s%c/%s}"), ct, tt == NULL ? '\n' : ' '); > if (tt == NULL) > goto end; > if (!tt->logout) { > @@ -393,7 +423,7 @@ printentry(struct utmpx *bp, struct idtab *tt) > tm = localtime(&tt->logout); > (void) strftime(ct, sizeof(ct), "%R", tm); > xo_attr("seconds", "%lu", (unsigned long)tt->logout); > - xo_emit("- {:logout-time/%s}", ct); > + xo_emit(ctf("- {:logout-time/%s}"), ct); > } > delta = tt->logout - bp->ut_tv.tv_sec; > xo_attr("seconds", "%ld", (long)delta); > @@ -403,9 +433,9 @@ printentry(struct utmpx *bp, struct idtab *tt) > tm = gmtime(&delta); > (void) strftime(ct, sizeof(ct), width >= 8 ? "%T" : "%R", tm); > if (delta < 86400) > - xo_emit(" ({:session-length/%s})\n", ct); > + xo_emit(ctf(" ({:session-length/%s})\n"), ct); > else > - xo_emit(" ({:session-length/%ld+%s})\n", > + xo_emit(ctf(" ({:session-length/%ld+%s})\n"), > (long)delta / 86400, ct); > } > >