VERSION = 1
PATCHLEVEL = 7
-SUBLEVEL = 1
+SUBLEVEL = 2
EXTRAVERSION =
NAME = Unnamed
/* vi: set sw=4 ts=4: */
/*
- * Copyright (C) 2003 by Glenn McGrath <bug1@iinet.net.au>
+ * Copyright (C) 2003 by Glenn McGrath
* SELinux support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
"group\0" No_argument "g"
"mode\0" No_argument "m"
"owner\0" No_argument "o"
+/* autofs build insists of using -b --suffix=.orig */
+/* TODO? (short option for --suffix is -S) */
#if ENABLE_SELINUX
"context\0" Required_argument "Z"
"preserve_context\0" No_argument "\xff"
#if ENABLE_SELINUX
-static bool use_default_selinux_context = 1;
-
static void setdefaultfilecon(const char *path)
{
struct stat s;
mode_t mode;
uid_t uid;
gid_t gid;
+ char *arg, *last;
const char *gid_str;
const char *uid_str;
const char *mode_str;
int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
- int ret = EXIT_SUCCESS, flags, i, isdir;
+ int flags;
+ int ret = EXIT_SUCCESS;
+ int isdir;
#if ENABLE_SELINUX
security_context_t scontext;
+ bool use_default_selinux_context = 1;
#endif
enum {
- OPT_CMD = 0x1,
- OPT_DIRECTORY = 0x2,
- OPT_PRESERVE_TIME = 0x4,
- OPT_STRIP = 0x8,
- OPT_GROUP = 0x10,
- OPT_MODE = 0x20,
- OPT_OWNER = 0x40,
+ OPT_c = 1 << 0,
+ OPT_v = 1 << 1,
+ OPT_b = 1 << 2,
+ OPT_DIRECTORY = 1 << 3,
+ OPT_PRESERVE_TIME = 1 << 4,
+ OPT_STRIP = 1 << 5,
+ OPT_GROUP = 1 << 6,
+ OPT_MODE = 1 << 7,
+ OPT_OWNER = 1 << 8,
#if ENABLE_SELINUX
- OPT_SET_SECURITY_CONTEXT = 0x80,
- OPT_PRESERVE_SECURITY_CONTEXT = 0x100,
+ OPT_SET_SECURITY_CONTEXT = 1 << 9,
+ OPT_PRESERVE_SECURITY_CONTEXT = 1 << 10,
#endif
};
#endif
opt_complementary = "s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z");
/* -c exists for backwards compatibility, it's needed */
-
- flags = getopt32(argv, "cdpsg:m:o:" USE_SELINUX("Z:"),
+ /* -v is ignored ("print name of each created directory") */
+ /* -b is ignored ("make a backup of each existing destination file") */
+ flags = getopt32(argv, "cvb" "dpsg:m:o:" USE_SELINUX("Z:"),
&gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext));
+ argc -= optind;
+ argv += optind;
#if ENABLE_SELINUX
- if (flags & OPT_PRESERVE_SECURITY_CONTEXT) {
- use_default_selinux_context = 0;
- copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
- selinux_or_die();
- }
- if (flags & OPT_SET_SECURITY_CONTEXT) {
+ if (flags & (OPT_PRESERVE_SECURITY_CONTEXT|OPT_SET_SECURITY_CONTEXT)) {
selinux_or_die();
- setfscreatecon_or_die(scontext);
use_default_selinux_context = 0;
- copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT;
+ if (flags & OPT_PRESERVE_SECURITY_CONTEXT) {
+ copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT;
+ }
+ if (flags & OPT_SET_SECURITY_CONTEXT) {
+ setfscreatecon_or_die(scontext);
+ copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT;
+ }
}
#endif
copy_flags |= FILEUTILS_PRESERVE_STATUS;
}
mode = 0666;
- if (flags & OPT_MODE) bb_parse_mode(mode_str, &mode);
+ if (flags & OPT_MODE)
+ bb_parse_mode(mode_str, &mode);
uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid();
gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();
- if (flags & (OPT_OWNER|OPT_GROUP)) umask(0);
+ if (flags & (OPT_OWNER|OPT_GROUP))
+ umask(0);
/* Create directories
* don't use bb_make_directory() as it can't change uid or gid
* perhaps bb_make_directory() should be improved.
*/
if (flags & OPT_DIRECTORY) {
- for (argv += optind; *argv; argv++) {
- char *old_argv_ptr = *argv + 1;
- char *argv_ptr;
- do {
- argv_ptr = strchr(old_argv_ptr, '/');
- old_argv_ptr = argv_ptr;
- if (argv_ptr) {
- *argv_ptr = '\0';
- old_argv_ptr++;
- }
- if (mkdir(*argv, mode | 0111) == -1) {
+ while ((arg = *argv++) != NULL) {
+ char *slash = arg;
+ while (1) {
+ slash = strchr(slash + 1, '/');
+ if (slash)
+ *slash = '\0';
+ if (mkdir(arg, mode | 0111) == -1) {
if (errno != EEXIST) {
- bb_perror_msg("cannot create %s", *argv);
+ bb_perror_msg("cannot create %s", arg);
ret = EXIT_FAILURE;
break;
}
- }
- if ((flags & (OPT_OWNER|OPT_GROUP))
- && lchown(*argv, uid, gid) == -1
+ } /* dir was created, chown? */
+ else if ((flags & (OPT_OWNER|OPT_GROUP))
+ && lchown(arg, uid, gid) == -1
) {
- bb_perror_msg("cannot change ownership of %s", *argv);
+ bb_perror_msg("cannot change ownership of %s", arg);
ret = EXIT_FAILURE;
break;
}
- if (argv_ptr) {
- *argv_ptr = '/';
- }
- } while (old_argv_ptr);
+ if (!slash)
+ break;
+ *slash = '/';
+ }
}
return ret;
}
- /* coreutils install resolves link in this case, don't use lstat */
- isdir = stat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
+ if (argc < 2)
+ bb_show_usage();
- for (i = optind; i < argc - 1; i++) {
- char *dest;
+ last = argv[argc - 1];
+ argv[argc - 1] = NULL;
+ /* coreutils install resolves link in this case, don't use lstat */
+ isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
- dest = argv[argc - 1];
+ while ((arg = *argv++) != NULL) {
+ char *dest = last;
if (isdir)
- dest = concat_path_file(argv[argc - 1], basename(argv[i]));
- ret |= copy_file(argv[i], dest, copy_flags);
+ dest = concat_path_file(last, basename(arg));
+ if (copy_file(arg, dest, copy_flags)) {
+ /* copy is not made */
+ ret = EXIT_FAILURE;
+ goto next;
+ }
/* Set the file mode */
if ((flags & OPT_MODE) && chmod(dest, mode) == -1) {
ret = EXIT_FAILURE;
}
}
- if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest);
+ next:
+ if (ENABLE_FEATURE_CLEAN_UP && isdir)
+ free(dest);
}
return ret;
#if ENABLE_FEATURE_FIND_XDEV
if (S_ISDIR(statbuf->st_mode) && xdev_count) {
for (i = 0; i < xdev_count; i++) {
- if (xdev_dev[i] != statbuf->st_dev)
- return SKIP;
+ if (xdev_dev[i] == statbuf->st_dev)
+ break;
}
+ if (i == xdev_count)
+ return SKIP;
}
#endif
i = exec_actions(actions, fileName, statbuf);
#endif
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
-static char *user_buf = (char*)"";
-static char *home_pwd_buf = (char*)"";
+static const char null_str[] = "";
+static char *user_buf;
+static char *home_pwd_buf = (char*)null_str;
#endif
/* Put 'command_ps[cursor]', cursor++.
if (with_shash_flg) { /* "~/..." or "~user/..." */
char *sav_ud = ud - 1;
- char *home = 0;
+ char *home = NULL;
char *temp;
if (*ud == '/') { /* "~/..." */
switch (c) {
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
case 'u':
- pbuf = user_buf;
+ pbuf = user_buf ? user_buf : (char*)"";
break;
#endif
case 'h':
case 'w':
pbuf = pwd_buf;
l = strlen(home_pwd_buf);
- if (home_pwd_buf[0] != 0
+ if (l != 0
&& strncmp(home_pwd_buf, pbuf, l) == 0
&& (pbuf[l]=='/' || pbuf[l]=='\0')
&& strlen(pwd_buf+l)<PATH_MAX
#undef CTRL
#define CTRL(a) ((a) & ~0x40)
+/* Returns:
+ * -1 on read errors or EOF, or on bare Ctrl-D.
+ * 0 on ctrl-C,
+ * >0 length of input string, including terminating '\n'
+ */
int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st)
{
int lastWasTab = FALSE;
entry = getpwuid(geteuid());
if (entry) {
+ /* If we enter read_line_input for the Nth time,
+ * they may be already allocated! Need to free. */
+ free(user_buf);
+ if (home_pwd_buf != null_str)
+ free(home_pwd_buf);
user_buf = xstrdup(entry->pw_name);
home_pwd_buf = xstrdup(entry->pw_dir);
+ /* They are not freed on exit (too small to bother) */
}
}
#endif
goto pam_auth_failed;
}
pamret = pam_authenticate(pamh, 0);
- if (pamret == PAM_SUCCESS) {
- char *pamuser;
- /* check that the account is healthy. */
- pamret = pam_acct_mgmt(pamh, 0);
- if (pamret != PAM_SUCCESS) {
- failed_msg = "account setup";
- goto pam_auth_failed;
- }
- /* read user back */
+ if (pamret != PAM_SUCCESS) {
+ failed_msg = "pam_authenticate";
+ goto pam_auth_failed;
+ /* TODO: or just "goto auth_failed"
+ * since user seems to enter wrong password
+ * (in this case pamret == 7)
+ */
+ }
+ /* check that the account is healthy */
+ pamret = pam_acct_mgmt(pamh, 0);
+ if (pamret != PAM_SUCCESS) {
+ failed_msg = "account setup";
+ goto pam_auth_failed;
+ }
+ /* read user back */
+ {
+ const char *pamuser;
/* gcc: "dereferencing type-punned pointer breaks aliasing rules..."
- * thus we use double cast */
- if (pam_get_item(pamh, PAM_USER, (const void **)(void*)&pamuser) != PAM_SUCCESS) {
+ * thus we cast to (void*) */
+ if (pam_get_item(pamh, PAM_USER, (void*)&pamuser) != PAM_SUCCESS) {
failed_msg = "pam_get_item(USER)";
goto pam_auth_failed;
}
break;
goto auth_failed;
pam_auth_failed:
- bb_error_msg("%s failed: %s", failed_msg, pam_strerror(pamh, pamret));
+ bb_error_msg("%s failed: %s (%d)", failed_msg, pam_strerror(pamh, pamret), pamret);
safe_strncpy(username, "UNKNOWN", sizeof(username));
#else /* not PAM */
pw = getpwnam(username);
auth_failed:
opt &= ~LOGIN_OPT_f;
bb_do_delay(FAIL_DELAY);
+ /* TODO: doesn't sound like correct English phrase to me */
puts("Login incorrect");
if (++count == 3) {
syslog(LOG_WARNING, "invalid password for '%s'%s",
tmp = pw->pw_shell;
if (!tmp || !*tmp)
tmp = DEFAULT_SHELL;
+ /* setup_environment params: shell, loginshell, changeenv, pw */
setup_environment(tmp, 1, !(opt & LOGIN_OPT_p), pw);
+ /* FIXME: login shell = 1 -> 3rd parameter is ignored! */
motd();
* should it leave SIGINT etc enabled or disabled? */
signal(SIGINT, SIG_DFL);
- run_shell(tmp, 1, 0, 0); /* exec the shell finally */
+ /* Exec login shell with no additional parameters */
+ run_shell(tmp, 1, NULL, NULL);
- return EXIT_FAILURE;
+ /* return EXIT_FAILURE; - not reached */
}
++p; /* so keep last character */
}
*p = '\0';
- sprintf(p0, "%s:%s", p0, c);
+ sprintf(p0 + strlen(p0), ":%s", c);
}
#endif
if (fromAddr->sa.sa_family == AF_INET) {
rmt_ip = ntohl(fromAddr->sin.sin_addr.s_addr);
}
+#if ENABLE_FEATURE_IPV6
+ if (fromAddr->sa.sa_family == AF_INET6
+ && fromAddr->sin6.sin6_addr.s6_addr32[0] == 0
+ && fromAddr->sin6.sin6_addr.s6_addr32[1] == 0
+ && ntohl(fromAddr->sin6.sin6_addr.s6_addr32[2]) == 0xffff)
+ rmt_ip = ntohl(fromAddr->sin6.sin6_addr.s6_addr32[3]);
+#endif
if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) {
rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->sa);
}
stamplog = now + 900;
}
}
- deadline = now + (check ? 1 : 5);
pfd[0].revents = 0;
sig_block(SIGCHLD);
+ deadline = (check ? 1 : 5);
if (rplog)
poll(pfd, 1, deadline*1000);
else
":\xff--urtl:u--\xff:r--\xff:t--\xff:l--\xff"
#endif
":f--v:v--f"; /* 'verbose' and 'quiet' are exclusive */
- getopt32(argv, "Rchf:u:r:t:l:v",
+ getopt32(argv, "Rchfu:r:t:l:v",
&user, &role, &type, &range, &reference_file);
argv += optind;
file_sep = strrchr(tmp_path, '/');
if (file_sep == tmp_path) {
file_sep++;
- p[0] = '\0';
+ path[0] = '\0';
p = path;
} else if (file_sep) {
*file_sep++ = '\0';
seek_sector(ullong secno)
{
secno *= sector_size;
+#if ENABLE_FDISK_SUPPORT_LARGE_DISKS
if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
fdisk_fatal(unable_to_seek);
+#else
+ if (secno > MAXINT(off_t)
+ || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1
+ ) {
+ fdisk_fatal(unable_to_seek);
+ }
+#endif
}
#if ENABLE_FEATURE_FDISK_WRITABLE