From 4890307abb587558e159f2397236a27f83ba6bde Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Fri, 6 Feb 2015 20:24:12 +0000 Subject: [PATCH] import Haiku changes, fix warnings. --- INSTALL | 4 +- lib/localcharset.c | 9 ++++- src/copy.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/copy.h | 3 ++ src/cp.c | 8 ++++ src/dircolors.h | 2 +- src/dircolors.hin | 2 +- src/ls.c | 13 ++++++- src/mv.c | 1 + src/remove.c | 2 +- src/uname.c | 28 ++++++++++++++ 11 files changed, 176 insertions(+), 7 deletions(-) diff --git a/INSTALL b/INSTALL index 2099840..3db7f81 100644 --- a/INSTALL +++ b/INSTALL @@ -247,10 +247,10 @@ directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. - On Haiku, software installed for all users goes in `/boot/common', + On Haiku, software installed for all users goes in `/boot/system', not `/usr/local'. It is recommended to use the following options: - ./configure --prefix=/boot/common + ./configure --prefix=/boot/system Specifying the System Type ========================== diff --git a/lib/localcharset.c b/lib/localcharset.c index a225a2e..644f151 100644 --- a/lib/localcharset.c +++ b/lib/localcharset.c @@ -127,7 +127,7 @@ get_charset_aliases (void) cp = charset_aliases; if (cp == NULL) { -#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) +#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__ || defined __HAIKU__) const char *dir; const char *base = "charset.alias"; char *file_name; @@ -341,6 +341,13 @@ get_charset_aliases (void) "CP54936" "\0" "GB18030" "\0" "CP65001" "\0" "UTF-8" "\0"; # endif + +# if defined __HAIKU__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + cp = "UTF-8" "\0"; +# endif #endif charset_aliases = cp; diff --git a/src/copy.c b/src/copy.c index 0f044d0..9284540 100644 --- a/src/copy.c +++ b/src/copy.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,10 @@ #include "yesno.h" #include "selinux.h" +#if (defined(__BEOS__) || defined(__HAIKU__)) +# include +#endif + #if USE_XATTR # include # include @@ -465,6 +470,92 @@ is_ancestor (const struct stat *sb, const struct dir_list *ancestors) return false; } + +static int +copy_attributes(int fromFd, int toFd) +{ + struct dirent *dirent; + char buffer[65536]; + + DIR *attributes = fs_fopen_attr_dir(fromFd); + if (attributes == NULL) + return errno == B_UNSUPPORTED ? 0 : -1; + + while ((dirent = fs_read_attr_dir(attributes)) != NULL) { + struct stat stat; + off_t pos = 0; + int attrFromFD = fs_fopen_attr(fromFd, dirent->d_name, 0, O_RDONLY); + int attrToFD; + + if (attrFromFD < 0) + continue; + + if (fstat(attrFromFD, &stat) != 0) { + close(attrFromFD); + continue; + } + + attrToFD = fs_fopen_attr(toFd, dirent->d_name, stat.st_type, + O_WRONLY | O_TRUNC | O_CREAT); + if (attrToFD < 0) { + close(attrFromFD); + continue; + } + + while (true) { + ssize_t bytesRead, bytesWritten; + + bytesRead = read_pos(attrFromFD, pos, buffer, sizeof(buffer)); + if (bytesRead < 0) { + fprintf(stderr, "error reading attribute '%s'", dirent->d_name); + break; + } + + bytesWritten = write_pos(attrToFD, pos, buffer, bytesRead); + if (bytesWritten != bytesRead) { + fprintf(stderr, "error writing attribute '%s'", dirent->d_name); + break; + } + + pos += bytesWritten; + stat.st_size -= bytesWritten; + + if (stat.st_size <= 0) + break; + } + close(attrToFD); + close(attrFromFD); + } + + fs_close_attr_dir(attributes); + return 0; +} + + +static int +copy_attributes_by_name(const char *from, const char *to, int resolveLinks) +{ + int fromFd, toFd, result; + + fromFd = open(from, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE)); + if (fromFd < 0) + return -1; + + toFd = open(to, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE)); + if (toFd < 0) { + close(fromFd); + return -1; + } + + result = copy_attributes(fromFd, toFd); + + close(fromFd); + close(toFd); + + return result; +} + + static bool errno_unsupported (int err) { @@ -598,6 +689,10 @@ copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, error (0, errno, _("cannot access %s"), quote (src_name_in)); return false; } + + if (x->ignore_attributes == 0 + && copy_attributes_by_name(src_name_in, dst_name_in, true) != 0) + fprintf(stderr, "%s: could not copy attributes\n", src_name_in); /* For cp's -H option, dereference command line arguments, but do not dereference symlinks that are found via recursive traversal. */ @@ -1266,6 +1361,11 @@ preserve_metadata: return_val = false; } } + + if (x->ignore_attributes == 0 + && copy_attributes(source_desc, dest_desc) != 0) + fprintf(stderr, "%s: could not copy attributes\n", src_name); + close_src_and_dst_desc: if (close (dest_desc) < 0) @@ -2198,6 +2298,12 @@ copy_internal (char const *src_name, char const *dst_name, dereference)) goto un_backup; + if (x->ignore_attributes == 0 + && copy_attributes_by_name (earlier_file, dst_name, + false) != 0) + error (0, errno, "cannot copy attributes from %s\n", + earlier_file); + return true; } } @@ -2589,6 +2695,11 @@ copy_internal (char const *src_name, char const *dst_name, preserving owner/group is a potential security problem. */ } } + + if (x->ignore_attributes == 0 + && copy_attributes_by_name(src_name, dst_name, false) != 0) + fprintf(stderr, "%s: could not copy attributes\n", src_name); + } else { diff --git a/src/copy.h b/src/copy.h index 4918d14..f0e309d 100644 --- a/src/copy.h +++ b/src/copy.h @@ -184,6 +184,9 @@ struct cp_options must be false. */ bool require_preserve; + /* If nonzero, attributes will be ignored when copying. */ + int ignore_attributes; + /* If true, attempt to preserve the SELinux security context, too. Set this only if the kernel is SELinux enabled. */ bool preserve_security_context; diff --git a/src/cp.c b/src/cp.c index 9038d4e..693f41e 100644 --- a/src/cp.c +++ b/src/cp.c @@ -73,6 +73,7 @@ struct dir_attr enum { ATTRIBUTES_ONLY_OPTION = CHAR_MAX + 1, + IGNORE_ATTRIBUTES, COPY_CONTENTS_OPTION, NO_PRESERVE_ATTRIBUTES_OPTION, PARENTS_OPTION, @@ -121,6 +122,7 @@ static struct option const long_opts[] = {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION}, {"dereference", no_argument, NULL, 'L'}, {"force", no_argument, NULL, 'f'}, + {"ignore-attributes", no_argument, NULL, IGNORE_ATTRIBUTES}, {"interactive", no_argument, NULL, 'i'}, {"link", no_argument, NULL, 'l'}, {"no-clobber", no_argument, NULL, 'n'}, @@ -179,6 +181,7 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ -f, --force if an existing destination file cannot be\n\ opened, remove it and try again (this option\n\ is ignored when the -n option is also used)\n\ + --ignore-attributes do not copy attributes\n\ -i, --interactive prompt before overwrite (overrides a previous -n\ \n\ option)\n\ @@ -797,6 +800,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; x->recursive = false; + x->ignore_attributes = false; x->sparse_mode = SPARSE_AUTO; x->symbolic_link = false; x->set_mode = false; @@ -1002,6 +1006,10 @@ main (int argc, char **argv) x.dereference = DEREF_COMMAND_LINE_ARGUMENTS; break; + case IGNORE_ATTRIBUTES: + x.ignore_attributes = true; + break; + case 'i': x.interactive = I_ASK_USER; break; diff --git a/src/dircolors.h b/src/dircolors.h index d7e7c58..7107020 100644 --- a/src/dircolors.h +++ b/src/dircolors.h @@ -87,7 +87,7 @@ static char const G_line[] = 'S','E','T','G','I','D',' ','3','0',';','4','3',' ','#',' ','f','i','l','e',' ','t','h','a','t',' ','i','s',' ','s','e','t','g','i','d',' ','(','g','+','s',')',0, 'C','A','P','A','B','I','L','I','T','Y',' ','3','0',';','4','1',' ','#',' ','f','i','l','e',' ','w','i','t','h',' ','c','a','p','a','b','i','l','i','t','y',0, 'S','T','I','C','K','Y','_','O','T','H','E','R','_','W','R','I','T','A','B','L','E',' ','3','0',';','4','2',' ','#',' ','d','i','r',' ','t','h','a','t',' ','i','s',' ','s','t','i','c','k','y',' ','a','n','d',' ','o','t','h','e','r','-','w','r','i','t','a','b','l','e',' ','(','+','t',',','o','+','w',')',0, - 'O','T','H','E','R','_','W','R','I','T','A','B','L','E',' ','3','4',';','4','2',' ','#',' ','d','i','r',' ','t','h','a','t',' ','i','s',' ','o','t','h','e','r','-','w','r','i','t','a','b','l','e',' ','(','o','+','w',')',' ','a','n','d',' ','n','o','t',' ','s','t','i','c','k','y',0, + 'O','T','H','E','R','_','W','R','I','T','A','B','L','E',' ','3','4',';','4','3',' ','#',' ','d','i','r',' ','t','h','a','t',' ','i','s',' ','o','t','h','e','r','-','w','r','i','t','a','b','l','e',' ','(','o','+','w',')',' ','a','n','d',' ','n','o','t',' ','s','t','i','c','k','y',0, 'S','T','I','C','K','Y',' ','3','7',';','4','4',' ','#',' ','d','i','r',' ','w','i','t','h',' ','t','h','e',' ','s','t','i','c','k','y',' ','b','i','t',' ','s','e','t',' ','(','+','t',')',' ','a','n','d',' ','n','o','t',' ','o','t','h','e','r','-','w','r','i','t','a','b','l','e',0, '#',' ','T','h','i','s',' ','i','s',' ','f','o','r',' ','f','i','l','e','s',' ','w','i','t','h',' ','e','x','e','c','u','t','e',' ','p','e','r','m','i','s','s','i','o','n',':',0, 'E','X','E','C',' ','0','1',';','3','2',0, diff --git a/src/dircolors.hin b/src/dircolors.hin index 0005cd0..03d6931 100644 --- a/src/dircolors.hin +++ b/src/dircolors.hin @@ -89,7 +89,7 @@ SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +OTHER_WRITABLE 34;43 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: diff --git a/src/ls.c b/src/ls.c index e7d1d93..c2db14f 100644 --- a/src/ls.c +++ b/src/ls.c @@ -676,6 +676,11 @@ static struct ignore_pattern *hide_patterns; want to mess up the terminal if control chars get sent to it, and some quoting methods pass through control chars as-is. */ static bool qmark_funny_chars; +#if defined(__HAIKU__) /* Default to show UTF8 chars in Haiku terminal. */ +#define QMARK_FUNNY_CHARS_TTY 0 +#else +#define QMARK_FUNNY_CHARS_TTY 1 +#endif /* Quoting options for file and dir name output. */ @@ -1524,7 +1529,7 @@ decode_switches (int argc, char **argv) bool sort_type_specified = false; bool kibibytes_specified = false; - qmark_funny_chars = false; + qmark_funny_chars = QMARK_FUNNY_CHARS_TTY; /* initialize all switches to default settings */ @@ -1548,7 +1553,9 @@ decode_switches (int argc, char **argv) { format = many_per_line; /* See description of qmark_funny_chars, above. */ +#ifndef __HAIKU__ qmark_funny_chars = true; +#endif } else { @@ -2098,11 +2105,13 @@ decode_switches (int argc, char **argv) } } +#ifdef HAVE_NL_LANGINFO /* Note we leave %5b etc. alone so user widths/flags are honored. */ if (strstr (long_time_format[0], "%b") || strstr (long_time_format[1], "%b")) if (!abmon_init ()) error (0, 0, _("error initializing month strings")); +#endif } return optind; @@ -3891,6 +3900,7 @@ print_long_format (const struct fileinfo *f) p = buf; } +#if !defined(__HAIKU__) if (f->stat_ok && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))) { @@ -3907,6 +3917,7 @@ print_long_format (const struct fileinfo *f) p += file_size_width + 1; } else +#endif { char hbuf[LONGEST_HUMAN_READABLE + 1]; char const *size = diff --git a/src/mv.c b/src/mv.c index b69b355..5a35254 100644 --- a/src/mv.c +++ b/src/mv.c @@ -125,6 +125,7 @@ cp_option_init (struct cp_options *x) x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ + x->ignore_attributes = false; x->require_preserve_context = false; x->preserve_xattr = true; x->require_preserve_xattr = false; diff --git a/src/remove.c b/src/remove.c index 3d386cf..6d22b31 100644 --- a/src/remove.c +++ b/src/remove.c @@ -215,7 +215,7 @@ prompt (FTS const *fts, FTSENT const *ent, bool is_dir, wp_errno = errno; } - if (write_protected || x->interactive == RMI_ALWAYS) + if (write_protected || errno || x->interactive == RMI_ALWAYS) { if (0 <= write_protected && dirent_type == DT_UNKNOWN) { diff --git a/src/uname.c b/src/uname.c index cfcd0a3..1aad4b6 100644 --- a/src/uname.c +++ b/src/uname.c @@ -49,6 +49,10 @@ # include #endif +#ifdef __HAIKU__ +# include +#endif + #include "system.h" #include "error.h" #include "quote.h" @@ -337,6 +341,30 @@ main (int argc, char **argv) # endif } #endif + +#ifdef __HAIKU__ + { + cpu_topology_node_info root; + uint32 count = 1; + status_t error = get_cpu_topology_info(&root, &count); + if (error != B_OK || count < 1) + element = "unknown"; + else { + switch (root.data.root.platform) { + case B_CPU_x86: + element = "x86"; + break; + case B_CPU_x86_64: + element = "x86_64"; + break; + default: + element = "other"; + break; + } + } + } +#endif + if (! (toprint == UINT_MAX && element == unknown)) print_element (element); } -- 1.8.3.4