Fri Oct 7 19:47:16 2016 UTC ()
Patch 0001 from upstream to tzcode2016g to restore full functionality
of zic -l


(kre)
diff -r1.63 -r1.64 src/lib/libc/time/zic.c

cvs diff -r1.63 -r1.64 src/lib/libc/time/zic.c (expand / switch to unified diff)

--- src/lib/libc/time/zic.c 2016/10/07 15:29:42 1.63
+++ src/lib/libc/time/zic.c 2016/10/07 19:47:16 1.64
@@ -1,26 +1,26 @@ @@ -1,26 +1,26 @@
1/* $NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $ */ 1/* $NetBSD: zic.c,v 1.64 2016/10/07 19:47:16 kre Exp $ */
2/* 2/*
3** This file is in the public domain, so clarified as of 3** This file is in the public domain, so clarified as of
4** 2006-07-17 by Arthur David Olson. 4** 2006-07-17 by Arthur David Olson.
5*/ 5*/
6 6
7#if HAVE_NBTOOL_CONFIG_H 7#if HAVE_NBTOOL_CONFIG_H
8#include "nbtool_config.h" 8#include "nbtool_config.h"
9#endif 9#endif
10 10
11#include <sys/cdefs.h> 11#include <sys/cdefs.h>
12#ifndef lint 12#ifndef lint
13__RCSID("$NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $"); 13__RCSID("$NetBSD: zic.c,v 1.64 2016/10/07 19:47:16 kre Exp $");
14#endif /* !defined lint */ 14#endif /* !defined lint */
15 15
16#include "private.h" 16#include "private.h"
17#include "locale.h" 17#include "locale.h"
18#include "tzfile.h" 18#include "tzfile.h"
19 19
20#include <stdarg.h> 20#include <stdarg.h>
21#include <unistd.h> 21#include <unistd.h>
22#include <util.h> 22#include <util.h>
23 23
24#define ZIC_VERSION_PRE_2013 '2' 24#define ZIC_VERSION_PRE_2013 '2'
25#define ZIC_VERSION '3' 25#define ZIC_VERSION '3'
26 26
@@ -766,26 +766,64 @@ namecheck(const char *name) @@ -766,26 +766,64 @@ namecheck(const char *name)
766 ? _("file name '%s' contains byte '%c'") 766 ? _("file name '%s' contains byte '%c'")
767 : _("file name '%s' contains byte '\\%o'")), 767 : _("file name '%s' contains byte '\\%o'")),
768 name, c); 768 name, c);
769 } 769 }
770 if (c == '/') { 770 if (c == '/') {
771 if (!componentcheck(name, component, cp)) 771 if (!componentcheck(name, component, cp))
772 return false; 772 return false;
773 component = cp + 1; 773 component = cp + 1;
774 } 774 }
775 } 775 }
776 return componentcheck(name, component, cp); 776 return componentcheck(name, component, cp);
777} 777}
778 778
 779/* Create symlink contents suitable for symlinking FROM to TO, as a
 780 freshly allocated string. FROM should be a relative file name, and
 781 is relative to the global variable DIRECTORY. TO can be either
 782 relative or absolute. */
 783static char *
 784relname(char const *from, char const *to)
 785{
 786 size_t i, taillen, dotdotetcsize;
 787 size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;
 788 char const *f = from;
 789 char *result = NULL;
 790 if (*to == '/') {
 791 /* Make F absolute too. */
 792 size_t len = strlen(directory);
 793 bool needslash = len && directory[len - 1] != '/';
 794 linksize = len + needslash + strlen(from) + 1;
 795 f = result = emalloc(linksize);
 796 strcpy(result, directory);
 797 result[len] = '/';
 798 strcpy(result + len + needslash, from);
 799 }
 800 for (i = 0; f[i] && f[i] == to[i]; i++)
 801 if (f[i] == '/')
 802 dir_len = i + 1;
 803 for (; f[i]; i++)
 804 dotdots += f[i] == '/' && f[i - 1] != '/';
 805 taillen = i - dir_len;
 806 dotdotetcsize = 3 * dotdots + taillen + 1;
 807 if (dotdotetcsize <= linksize) {
 808 if (!result)
 809 result = emalloc(dotdotetcsize);
 810 for (i = 0; i < dotdots; i++)
 811 memcpy(result + 3 * i, "../", 3);
 812 memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
 813 }
 814 return result;
 815}
 816
779static void 817static void
780dolink(char const *fromfield, char const *tofield, bool staysymlink) 818dolink(char const *fromfield, char const *tofield, bool staysymlink)
781{ 819{
782 int fromisdir; 820 int fromisdir;
783 bool todirs_made = false; 821 bool todirs_made = false;
784 int link_errno; 822 int link_errno;
785 823
786 /* 824 /*
787 ** We get to be careful here since 825 ** We get to be careful here since
788 ** there's a fair chance of root running us. 826 ** there's a fair chance of root running us.
789 */ 827 */
790 fromisdir = itsdir(fromfield); 828 fromisdir = itsdir(fromfield);
791 if (fromisdir) { 829 if (fromisdir) {
@@ -802,50 +840,35 @@ dolink(char const *fromfield, char const @@ -802,50 +840,35 @@ dolink(char const *fromfield, char const
802 char const *e = strerror(errno); 840 char const *e = strerror(errno);
803 fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"), 841 fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
804 progname, directory, tofield, e); 842 progname, directory, tofield, e);
805 exit(EXIT_FAILURE); 843 exit(EXIT_FAILURE);
806 } 844 }
807 link_errno = (staysymlink ? ENOTSUP 845 link_errno = (staysymlink ? ENOTSUP
808 : link(fromfield, tofield) == 0 ? 0 : errno); 846 : link(fromfield, tofield) == 0 ? 0 : errno);
809 if (link_errno == ENOENT && !todirs_made) { 847 if (link_errno == ENOENT && !todirs_made) {
810 mkdirs(tofield, true); 848 mkdirs(tofield, true);
811 todirs_made = true; 849 todirs_made = true;
812 link_errno = link(fromfield, tofield) == 0 ? 0 : errno; 850 link_errno = link(fromfield, tofield) == 0 ? 0 : errno;
813 } 851 }
814 if (link_errno != 0) { 852 if (link_errno != 0) {
815 const char *s = fromfield; 853 bool absolute = *fromfield == '/';
816 const char *t; 854 char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
817 char *p; 855 char const *contents = absolute ? fromfield : linkalloc;
818 size_t dotdots = 0; 856 int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
819 char *symlinkcontents; 
820 int symlink_errno; 
821 
822 do 
823 t = s; 
824 while ((s = strchr(s, '/')) 
825 && strncmp(fromfield, tofield, ++s - fromfield) == 0); 
826 
827 for (s = tofield + (t - fromfield); *s; s++) 
828 dotdots += *s == '/'; 
829 symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1); 
830 for (p = symlinkcontents; dotdots-- != 0; p += 3) 
831 memcpy(p, "../", 3); 
832 strcpy(p, t); 
833 symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno; 
834 if (symlink_errno == ENOENT && !todirs_made) { 857 if (symlink_errno == ENOENT && !todirs_made) {
835 mkdirs(tofield, true); 858 mkdirs(tofield, true);
836 symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno; 859 symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
837 } 860 }
838 free(symlinkcontents); 861 free(linkalloc);
839 if (symlink_errno == 0) { 862 if (symlink_errno == 0) {
840 if (link_errno != ENOTSUP) 863 if (link_errno != ENOTSUP)
841 warning(_("symbolic link used because hard link failed: %s"), 864 warning(_("symbolic link used because hard link failed: %s"),
842 strerror(link_errno)); 865 strerror(link_errno));
843 } else { 866 } else {
844 FILE *fp, *tp; 867 FILE *fp, *tp;
845 int c; 868 int c;
846 fp = fopen(fromfield, "rb"); 869 fp = fopen(fromfield, "rb");
847 if (!fp) { 870 if (!fp) {
848 char const *e = strerror(errno); 871 char const *e = strerror(errno);
849 fprintf(stderr, _("%s: Can't read %s/%s: %s\n"), 872 fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
850 progname, directory, fromfield, e); 873 progname, directory, fromfield, e);
851 exit(EXIT_FAILURE); 874 exit(EXIT_FAILURE);