Exemple #1
0
int
do_move(char *from, char *to)
{
	struct stat sb, fsb;
	char modep[15];

	/* Source path must exist (symlink is OK). */
	if (lstat(from, &fsb)) {
		warn("%s", from);
		return (1);
	}

	/*
	 * (1)	If the destination path exists, the -f option is not specified
	 *	and either of the following conditions are true:
	 *
	 *	(a) The permissions of the destination path do not permit
	 *	    writing and the standard input is a terminal.
	 *	(b) The -i option is specified.
	 *
	 *	the mv utility shall write a prompt to standard error and
	 *	read a line from standard input.  If the response is not
	 *	affirmative, mv shall do nothing more with the current
	 *	source file...
	 */
	if (!fflg && !access(to, F_OK)) {
		int ask = 1;
		int ch, first;

		if (iflg && !access(from, F_OK)) {
			(void)fprintf(stderr, "overwrite %s? ", to);
		} else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) {
			strmode(sb.st_mode, modep);
			(void)fprintf(stderr, "override %s%s%s/%s for %s? ",
			    modep + 1, modep[9] == ' ' ? "" : " ",
			    user_from_uid(sb.st_uid, 0),
			    group_from_gid(sb.st_gid, 0), to);
		} else
			ask = 0;
		if (ask) {
			first = ch = getchar();
			while (ch != '\n' && ch != EOF)
				ch = getchar();
			if (first != 'y' && first != 'Y')
				return (0);
		}
	}

	/*
	 * (2)	If rename() succeeds, mv shall do nothing more with the
	 *	current source file.  If it fails for any other reason than
	 *	EXDEV, mv shall write a diagnostic message to the standard
	 *	error and do nothing more with the current source file.
	 *
	 * (3)	If the destination path exists, and it is a file of type
	 *	directory and source_file is not a file of type directory,
	 *	or it is a file not of type directory, and source file is
	 *	a file of type directory, mv shall write a diagnostic
	 *	message to standard error, and do nothing more with the
	 *	current source file...
	 */
	if (!rename(from, to))
		return (0);

	if (errno != EXDEV) {
		warn("rename %s to %s", from, to);
		return (1);
	}

#ifndef OBASE
	/* Disallow moving a mount point. */
	if (S_ISDIR(fsb.st_mode)) {
		struct statfs sfs;
		char path[MAXPATHLEN];

		if (realpath(from, path) == NULL) {
			warnx("cannot resolve %s", from);
			return (1);
		}
		if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname)) {
			warnx("cannot rename a mount point");
			return (1);
		}
	}
#endif

	/*
	 * (4)	If the destination path exists, mv shall attempt to remove it.
	 *	If this fails for any reason, mv shall write a diagnostic
	 *	message to the standard error and do nothing more with the
	 *	current source file...
	 */
	if (!lstat(to, &sb)) {
		if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) {
			warn("can't remove %s", to);
			return (1);
		}
	}

	/*
	 * (5)	The file hierarchy rooted in source_file shall be duplicated
	 *	as a file hierarchy rooted in the destination path...
	 */
	return (S_ISREG(fsb.st_mode) ?
	    fastcopy(from, to, &fsb) : copy(from, to));
}
static LONGEST
linux_xfer_osdata_shm (gdb_byte *readbuf,
		       ULONGEST offset, ULONGEST len)
{
  static const char *buf;
  static LONGEST len_avail = -1;
  static struct buffer buffer;

  if (offset == 0)
    {
      FILE *fp;

      if (len_avail != -1 && len_avail != 0)
	buffer_free (&buffer);
      len_avail = 0;
      buf = NULL;
      buffer_init (&buffer);
      buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");

      fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
      if (fp)
	{
	  char buf[8192];

	  do
	    {
	      if (fgets (buf, sizeof (buf), fp))
		{
		  key_t key;
		  uid_t uid, cuid;
		  gid_t gid, cgid;
		  PID_T cpid, lpid;
		  int shmid, size, nattch;
		  TIME_T atime, dtime, ctime;
		  unsigned int perms;
		  int items_read;
				  
		  items_read = sscanf (buf,
				       "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
				       &key, &shmid, &perms, &size,
				       &cpid, &lpid,
				       &nattch,
				       &uid, &gid, &cuid, &cgid,
				       &atime, &dtime, &ctime);

		  if (items_read == 14)
		    {
		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
		      char ccmd[32], lcmd[32];
		      char atime_str[32], dtime_str[32], ctime_str[32];
		      
		      user_from_uid (user, sizeof (user), uid);
		      group_from_gid (group, sizeof (group), gid);
		      user_from_uid (cuser, sizeof (cuser), cuid);
		      group_from_gid (cgroup, sizeof (cgroup), cgid);
		      
		      command_from_pid (ccmd, sizeof (ccmd), cpid);
		      command_from_pid (lcmd, sizeof (lcmd), lpid);
		      
		      time_from_time_t (atime_str, sizeof (atime_str), atime);
		      time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
		      
		      buffer_xml_printf (
		          &buffer,
			  "<item>"
			  "<column name=\"key\">%d</column>"
			  "<column name=\"shmid\">%d</column>"
			  "<column name=\"permissions\">%o</column>"
			  "<column name=\"size\">%d</column>"
			  "<column name=\"creator command\">%s</column>"
			  "<column name=\"last op. command\">%s</column>"
			  "<column name=\"num attached\">%d</column>"
			  "<column name=\"user\">%s</column>"
			  "<column name=\"group\">%s</column>"
			  "<column name=\"creator user\">%s</column>"
			  "<column name=\"creator group\">%s</column>"
			  "<column name=\"last shmat() time\">%s</column>"
			  "<column name=\"last shmdt() time\">%s</column>"
			  "<column name=\"last shmctl() time\">%s</column>"
			  "</item>",
			  key,
			  shmid,
			  perms,
			  size,
			  ccmd,
			  lcmd,
			  nattch,
			  user,
			  group,
			  cuser,
			  cgroup,
			  atime_str,
			  dtime_str,
			  ctime_str);
		    }
		}
	    }
	  while (!feof (fp));

	  fclose (fp);
	}
      
      buffer_grow_str0 (&buffer, "</osdata>\n");
      buf = buffer_finish (&buffer);
      len_avail = strlen (buf);
    }

  if (offset >= len_avail)
    {
      /* Done.  Get rid of the buffer.  */
      buffer_free (&buffer);
      buf = NULL;
      len_avail = 0;
      return 0;
    }

  if (len > len_avail - offset)
    len = len_avail - offset;
  memcpy (readbuf, buf + offset, len);

  return len;
}
Exemple #3
0
/*
 * Display() takes a linked list of FTSENT structures and passes the list
 * along with any other necessary information to the print function.  P
 * points to the parent directory of the display list.
 */
static void
display(FTSENT *p, FTSENT *list)
{
    struct stat *sp;
    DISPLAY d;
    FTSENT *cur;
    NAMES *np;
    ULLT btotal, maxblock, maxsize;
    int maxinode, maxnlink, maxmajor, maxminor;
    int bcfile, entries, flen, glen, ulen, maxflags, maxgroup, maxlen;
    int maxuser, needstats;
    const char *user, *group;
    char buf[21];		/* 64 bits == 20 digits, +1 for NUL */
    char nuser[12], ngroup[12];
    char *flags = NULL;

#ifdef __GNUC__
    /* This outrageous construct just to shut up a GCC warning. */
    (void) &maxsize;
#endif

    /*
     * If list is NULL there are two possibilities: that the parent
     * directory p has no children, or that fts_children() returned an
     * error.  We ignore the error case since it will be replicated
     * on the next call to fts_read() on the post-order visit to the
     * directory p, and will be signalled in traverse().
     */
    if (list == NULL)
        return;

    needstats = f_inode || f_longform || f_size;
    flen = 0;
    maxinode = maxnlink = 0;
    bcfile = 0;
    maxuser = maxgroup = maxflags = maxlen = 0;
    btotal = maxblock = maxsize = 0;
    maxmajor = maxminor = 0;
    for (cur = list, entries = 0; cur; cur = cur->fts_link) {
        if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
            warnx("%s: %s",
                  cur->fts_name, strerror(cur->fts_errno));
            cur->fts_number = NO_PRINT;
            rval = EXIT_FAILURE;
            continue;
        }

        /*
         * P is NULL if list is the argv list, to which different rules
         * apply.
         */
        if (p == NULL) {
            /* Directories will be displayed later. */
            if (cur->fts_info == FTS_D && !f_listdir) {
                cur->fts_number = NO_PRINT;
                continue;
            }
        } else {
            /* Only display dot file if -a/-A set. */
            if (cur->fts_name[0] == '.' && !f_listdot) {
                cur->fts_number = NO_PRINT;
                continue;
            }
        }
        if (cur->fts_namelen > maxlen)
            maxlen = cur->fts_namelen;
        if (needstats) {
            sp = cur->fts_statp;
            if (sp->st_blocks > maxblock)
                maxblock = sp->st_blocks;
            if (sp->st_ino > maxinode)
                maxinode = sp->st_ino;
            if (sp->st_nlink > maxnlink)
                maxnlink = sp->st_nlink;
            if (sp->st_size > maxsize)
                maxsize = sp->st_size;
            if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) {
                bcfile = 1;
                if (major(sp->st_rdev) > maxmajor)
                    maxmajor = major(sp->st_rdev);
                if (minor(sp->st_rdev) > maxminor)
                    maxminor = minor(sp->st_rdev);
            }

            btotal += sp->st_blocks;
            if (f_longform) {
                if (f_numericonly ||
                        (user = user_from_uid(sp->st_uid, 0)) ==
                        NULL) {
                    (void)snprintf(nuser, sizeof(nuser),
                                   "%u", sp->st_uid);
                    user = nuser;
                }
                if (f_numericonly ||
                        (group = group_from_gid(sp->st_gid, 0)) ==
                        NULL) {
                    (void)snprintf(ngroup, sizeof(ngroup),
                                   "%u", sp->st_gid);
                    group = ngroup;
                }
                if ((ulen = strlen(user)) > maxuser)
                    maxuser = ulen;
                if ((glen = strlen(group)) > maxgroup)
                    maxgroup = glen;
#if !defined(HAVE_TNFTPD_H)
                if (f_flags) {
                    flags =
                        flags_to_string(sp->st_flags, "-");
                    if ((flen = strlen(flags)) > maxflags)
                        maxflags = flen;
                } else
#endif /* !defined(HAVE_TNFTPD_H) */
                    flen = 0;

                if ((np = malloc(sizeof(NAMES) +
                                 ulen + glen + flen + 3)) == NULL)
                    err(EXIT_FAILURE, NULL);

                np->user = &np->data[0];
                (void)strcpy(np->user, user);
                np->group = &np->data[ulen + 1];
                (void)strcpy(np->group, group);

                if (f_flags) {
                    np->flags = &np->data[ulen + glen + 2];
                    (void)strcpy(np->flags, flags);
                }
                cur->fts_pointer = np;
            }
        }
        ++entries;
    }

    if (!entries)
        return;

    d.list = list;
    d.entries = entries;
    d.maxlen = maxlen;
    if (needstats) {
        d.btotal = btotal;
        (void)snprintf(buf, sizeof(buf), ULLF,
                       (ULLT)howmany(maxblock, blocksize));
        d.s_block = strlen(buf);
        d.s_flags = maxflags;
        d.s_group = maxgroup;
        (void)snprintf(buf, sizeof(buf), "%u", maxinode);
        d.s_inode = strlen(buf);
        (void)snprintf(buf, sizeof(buf), "%u", maxnlink);
        d.s_nlink = strlen(buf);
        (void)snprintf(buf, sizeof(buf), ULLF, (ULLT)maxsize);
        d.s_size = strlen(buf);
        d.s_user = maxuser;
        if (bcfile) {
            (void)snprintf(buf, sizeof(buf), "%u", maxmajor);
            d.s_major = strlen(buf);
            (void)snprintf(buf, sizeof(buf), "%u", maxminor);
            d.s_minor = strlen(buf);
            if (d.s_major + d.s_minor + 2 > d.s_size)
                d.s_size = d.s_major + d.s_minor + 2;
            else if (d.s_size - d.s_minor - 2 > d.s_major)
                d.s_major = d.s_size - d.s_minor - 2;
        } else {
            d.s_major = 0;
            d.s_minor = 0;
        }
    }

    printfcn(&d);
    output = 1;

    if (f_longform)
        for (cur = list; cur; cur = cur->fts_link)
            free(cur->fts_pointer);
}
Exemple #4
0
static int
do_move(const char *from, const char *to)
{
	struct stat sb;
	int ask, ch, first;
	char modep[15];

	/*
	 * Check access.  If interactive and file exists, ask user if it
	 * should be replaced.  Otherwise if file exists but isn't writable
	 * make sure the user wants to clobber it.
	 */
	if (!fflg && !access(to, F_OK)) {

		/* prompt only if source exist */
	        if (lstat(from, &sb) == -1) {
			warn("%s", from);
			return (1);
		}

#define YESNO "(y/n [n]) "
		ask = 0;
		if (nflg) {
			if (vflg)
				printf("%s not overwritten\n", to);
			return (0);
		} else if (iflg) {
			(void)fprintf(stderr, "overwrite %s? %s", to, YESNO);
			ask = 1;
		} else if (access(to, W_OK) && !stat(to, &sb)) {
			strmode(sb.st_mode, modep);
			(void)fprintf(stderr, "override %s%s%s/%s for %s? %s",
			    modep + 1, modep[9] == ' ' ? "" : " ",
			    user_from_uid((unsigned long)sb.st_uid, 0),
			    group_from_gid((unsigned long)sb.st_gid, 0), to, YESNO);
			ask = 1;
		}
		if (ask) {
			first = ch = getchar();
			while (ch != '\n' && ch != EOF)
				ch = getchar();
			if (first != 'y' && first != 'Y') {
				(void)fprintf(stderr, "not overwritten\n");
				return (0);
			}
		}
	}
	/*
	 * Rename on FreeBSD will fail with EISDIR and ENOTDIR, before failing
	 * with EXDEV.  Therefore, copy() doesn't have to perform the checks
	 * specified in the Step 3 of the POSIX mv specification.
	 */
	if (!rename(from, to)) {
		if (vflg)
			printf("%s -> %s\n", from, to);
		return (0);
	}

	if (errno == EXDEV) {
		struct statfs sfs;
		char path[PATH_MAX];

		/*
		 * If the source is a symbolic link and is on another
		 * filesystem, it can be recreated at the destination.
		 */
		if (lstat(from, &sb) == -1) {
			warn("%s", from);
			return (1);
		}
		if (!S_ISLNK(sb.st_mode)) {
			/* Can't mv(1) a mount point. */
			if (realpath(from, path) == NULL) {
				warn("cannot resolve %s: %s", from, path);
				return (1);
			}
			if (!statfs(path, &sfs) &&
			    !strcmp(path, sfs.f_mntonname)) {
				warnx("cannot rename a mount point");
				return (1);
			}
		}
	} else {
		warn("rename %s to %s", from, to);
		return (1);
	}

	/*
	 * If rename fails because we're trying to cross devices, and
	 * it's a regular file, do the copy internally; otherwise, use
	 * cp and rm.
	 */
	if (lstat(from, &sb)) {
		warn("%s", from);
		return (1);
	}
	return (S_ISREG(sb.st_mode) ?
	    fastcopy(from, to, &sb) : copy(from, to));
}
Exemple #5
0
void
rgname(const struct kinfo_proc *kp, VARENT *ve)
{
	mbswprint(group_from_gid(kp->p_rgid, 0), ve->var->width,
	    ve->next != NULL);
}
Exemple #6
0
/*
 * Display() takes a linked list of FTSENT structures and passes the list
 * along with any other necessary information to the print function.  P
 * points to the parent directory of the display list.
 */
static void
display(const FTSENT *p, FTSENT *list, int options)
{
	struct stat *sp;
	DISPLAY d;
	FTSENT *cur;
	NAMES *np;
	off_t maxsize;
	long maxblock;
	uintmax_t maxinode;
	u_long btotal, labelstrlen, maxlen, maxnlink;
	u_long maxlabelstr;
	u_int sizelen;
	int maxflags;
	gid_t maxgroup;
	uid_t maxuser;
	size_t flen, ulen, glen;
	char *initmax;
	int entries, needstats;
	const char *user, *group;
	char *flags, *labelstr = NULL;
	char ngroup[STRBUF_SIZEOF(uid_t) + 1];
	char nuser[STRBUF_SIZEOF(gid_t) + 1];

	needstats = f_inode || f_longform || f_size;
	flen = 0;
	btotal = 0;
	initmax = getenv("LS_COLWIDTHS");
	/* Fields match -lios order.  New ones should be added at the end. */
	maxlabelstr = maxblock = maxlen = maxnlink = 0;
	maxuser = maxgroup = maxflags = maxsize = 0;
	maxinode = 0;
	if (initmax != NULL && *initmax != '\0') {
		char *initmax2, *jinitmax;
		int ninitmax;

		/* Fill-in "::" as "0:0:0" for the sake of scanf. */
		jinitmax = malloc(strlen(initmax) * 2 + 2);
		if (jinitmax == NULL)
			err(1, "malloc");
		initmax2 = jinitmax;
		if (*initmax == ':')
			strcpy(initmax2, "0:"), initmax2 += 2;
		else
			*initmax2++ = *initmax, *initmax2 = '\0';
		for (initmax++; *initmax != '\0'; initmax++) {
			if (initmax[-1] == ':' && initmax[0] == ':') {
				*initmax2++ = '0';
				*initmax2++ = initmax[0];
				initmax2[1] = '\0';
			} else {
				*initmax2++ = initmax[0];
				initmax2[1] = '\0';
			}
		}
		if (initmax2[-1] == ':')
			strcpy(initmax2, "0");

		ninitmax = sscanf(jinitmax,
		    " %ju : %ld : %lu : %u : %u : %i : %jd : %lu : %lu ",
		    &maxinode, &maxblock, &maxnlink, &maxuser,
		    &maxgroup, &maxflags, &maxsize, &maxlen, &maxlabelstr);
		f_notabs = 1;
		switch (ninitmax) {
		case 0:
			maxinode = 0;
			/* FALLTHROUGH */
		case 1:
			maxblock = 0;
			/* FALLTHROUGH */
		case 2:
			maxnlink = 0;
			/* FALLTHROUGH */
		case 3:
			maxuser = 0;
			/* FALLTHROUGH */
		case 4:
			maxgroup = 0;
			/* FALLTHROUGH */
		case 5:
			maxflags = 0;
			/* FALLTHROUGH */
		case 6:
			maxsize = 0;
			/* FALLTHROUGH */
		case 7:
			maxlen = 0;
			/* FALLTHROUGH */
		case 8:
			maxlabelstr = 0;
			/* FALLTHROUGH */
#ifdef COLORLS
			if (!f_color)
#endif
				f_notabs = 0;
			/* FALLTHROUGH */
		default:
			break;
		}
		MAKENINES(maxinode);
		MAKENINES(maxblock);
		MAKENINES(maxnlink);
		MAKENINES(maxsize);
		free(jinitmax);
	}
	d.s_size = 0;
	sizelen = 0;
	flags = NULL;
	for (cur = list, entries = 0; cur; cur = cur->fts_link) {
		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
			warnx("%s: %s",
			    cur->fts_name, strerror(cur->fts_errno));
			cur->fts_number = NO_PRINT;
			rval = 1;
			continue;
		}
		/*
		 * P is NULL if list is the argv list, to which different rules
		 * apply.
		 */
		if (p == NULL) {
			/* Directories will be displayed later. */
			if (cur->fts_info == FTS_D && !f_listdir) {
				cur->fts_number = NO_PRINT;
				continue;
			}
		} else {
			/* Only display dot file if -a/-A set. */
			if (cur->fts_name[0] == '.' && !f_listdot) {
				cur->fts_number = NO_PRINT;
				continue;
			}
		}
		if (cur->fts_namelen > maxlen)
			maxlen = cur->fts_namelen;
		if (f_octal || f_octal_escape) {
			u_long t = len_octal(cur->fts_name, cur->fts_namelen);

			if (t > maxlen)
				maxlen = t;
		}
		if (needstats) {
			sp = cur->fts_statp;
			if (sp->st_blocks > maxblock)
				maxblock = sp->st_blocks;
			if (sp->st_ino > maxinode)
				maxinode = sp->st_ino;
			if (sp->st_nlink > maxnlink)
				maxnlink = sp->st_nlink;
			if (sp->st_size > maxsize)
				maxsize = sp->st_size;

			btotal += sp->st_blocks;
			if (f_longform) {
				if (f_numericonly) {
					(void)snprintf(nuser, sizeof(nuser),
					    "%u", sp->st_uid);
					(void)snprintf(ngroup, sizeof(ngroup),
					    "%u", sp->st_gid);
					user = nuser;
					group = ngroup;
				} else {
					user = user_from_uid(sp->st_uid, 0);
					group = group_from_gid(sp->st_gid, 0);
				}
				if ((ulen = strlen(user)) > maxuser)
					maxuser = ulen;
				if ((glen = strlen(group)) > maxgroup)
					maxgroup = glen;
				if (f_flags) {
					flags = fflagstostr(sp->st_flags);
					if (flags != NULL && *flags == '\0') {
						free(flags);
						flags = strdup("-");
					}
					if (flags == NULL)
						err(1, "fflagstostr");
					flen = strlen(flags);
					if (flen > (size_t)maxflags)
						maxflags = flen;
				} else
					flen = 0;
				labelstr = NULL;
				if (f_label) {
					char name[PATH_MAX + 1];
					mac_t label;
					int error;

					error = mac_prepare_file_label(&label);
					if (error == -1) {
						warn("MAC label for %s/%s",
						    cur->fts_parent->fts_path,
						    cur->fts_name);
						goto label_out;
					}

					if (cur->fts_level == FTS_ROOTLEVEL)
						snprintf(name, sizeof(name),
						    "%s", cur->fts_name);
					else
						snprintf(name, sizeof(name),
						    "%s/%s", cur->fts_parent->
						    fts_accpath, cur->fts_name);

					if (options & FTS_LOGICAL)
						error = mac_get_file(name,
						    label);
					else
						error = mac_get_link(name,
						    label);
					if (error == -1) {
						warn("MAC label for %s/%s",
						    cur->fts_parent->fts_path,
						    cur->fts_name);
						mac_free(label);
						goto label_out;
					}

					error = mac_to_text(label,
					    &labelstr);
					if (error == -1) {
						warn("MAC label for %s/%s",
						    cur->fts_parent->fts_path,
						    cur->fts_name);
						mac_free(label);
						goto label_out;
					}
					mac_free(label);
label_out:
					if (labelstr == NULL)
						labelstr = strdup("-");
					labelstrlen = strlen(labelstr);
					if (labelstrlen > maxlabelstr)
						maxlabelstr = labelstrlen;
				} else
					labelstrlen = 0;

				if ((np = malloc(sizeof(NAMES) + labelstrlen +
				    ulen + glen + flen + 4)) == NULL)
					err(1, "malloc");

				np->user = &np->data[0];
				(void)strcpy(np->user, user);
				np->group = &np->data[ulen + 1];
				(void)strcpy(np->group, group);

				if (S_ISCHR(sp->st_mode) ||
				    S_ISBLK(sp->st_mode)) {
					sizelen = snprintf(NULL, 0,
					    "%#jx", (uintmax_t)sp->st_rdev);
					if (d.s_size < sizelen)
						d.s_size = sizelen;
				}

				if (f_flags) {
					np->flags = &np->data[ulen + glen + 2];
					(void)strcpy(np->flags, flags);
					free(flags);
				}
				if (f_label) {
					np->label = &np->data[ulen + glen + 2
					    + (f_flags ? flen + 1 : 0)];
					(void)strcpy(np->label, labelstr);
					free(labelstr);
				}
				cur->fts_pointer = np;
			}
		}
		++entries;
	}

	/*
	 * If there are no entries to display, we normally stop right
	 * here.  However, we must continue if we have to display the
	 * total block count.  In this case, we display the total only
	 * on the second (p != NULL) pass.
	 */
	if (!entries && (!(f_longform || f_size) || p == NULL))
		return;

	d.list = list;
	d.entries = entries;
	d.maxlen = maxlen;
	if (needstats) {
		d.btotal = btotal;
		d.s_block = snprintf(NULL, 0, "%lu", howmany(maxblock, blocksize));
		d.s_flags = maxflags;
		d.s_label = maxlabelstr;
		d.s_group = maxgroup;
		d.s_inode = snprintf(NULL, 0, "%ju", maxinode);
		d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink);
		sizelen = f_humanval ? HUMANVALSTR_LEN :
		    snprintf(NULL, 0, "%ju", maxsize);
		if (d.s_size < sizelen)
			d.s_size = sizelen;
		d.s_user = maxuser;
	}
	if (f_thousands)			/* make space for commas */
		d.s_size += (d.s_size - 1) / 3;
	printfcn(&d);
	output = 1;

	if (f_longform)
		for (cur = list; cur; cur = cur->fts_link)
			free(cur->fts_pointer);
}
Exemple #7
0
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode,
      u_long *pflags)
{
	FTSENT *p;
	gid_t sgid;
	uid_t suid;
	mode_t smode;
	u_long sflags = 0;
	const char *name = NULL;
	gid_t savegid;
	uid_t saveuid;
	mode_t savemode;
	u_long saveflags;
	u_short maxgid, maxuid, maxmode, maxflags;
	u_short g[MTREE_MAXGID], u[MTREE_MAXUID],
		m[MTREE_MAXMODE], f[MTREE_MAXFLAGS];
	static int first = 1;

	savegid = *pgid;
	saveuid = *puid;
	savemode = *pmode;
	saveflags = *pflags;
	if ((p = fts_children(t, 0)) == NULL) {
		if (errno)
			mtree_err("%s: %s", RP(parent), strerror(errno));
		return (1);
	}

	memset(g, 0, sizeof(g));
	memset(u, 0, sizeof(u));
	memset(m, 0, sizeof(m));
	memset(f, 0, sizeof(f));

	maxuid = maxgid = maxmode = maxflags = 0;
	for (; p; p = p->fts_link) {
		if (flavor == F_NETBSD6 || !dflag ||
		    (dflag && S_ISDIR(p->fts_statp->st_mode))) {
			smode = p->fts_statp->st_mode & MBITS;
			if (smode < MTREE_MAXMODE && ++m[smode] > maxmode) {
				savemode = smode;
				maxmode = m[smode];
			}
			sgid = p->fts_statp->st_gid;
			if (sgid < MTREE_MAXGID && ++g[sgid] > maxgid) {
				savegid = sgid;
				maxgid = g[sgid];
			}
			suid = p->fts_statp->st_uid;
			if (suid < MTREE_MAXUID && ++u[suid] > maxuid) {
				saveuid = suid;
				maxuid = u[suid];
			}

#if HAVE_STRUCT_STAT_ST_FLAGS
			sflags = FLAGS2INDEX(p->fts_statp->st_flags);
			if (sflags < MTREE_MAXFLAGS && ++f[sflags] > maxflags) {
				saveflags = p->fts_statp->st_flags;
				maxflags = f[sflags];
			}
#endif
		}
	}
	/*
	 * If the /set record is the same as the last one we do not need to
	 * output a new one.  So first we check to see if anything changed.
	 * Note that we always output a /set record for the first directory.
	 */
	if (((keys & (F_UNAME | F_UID)) && (*puid != saveuid)) ||
	    ((keys & (F_GNAME | F_GID)) && (*pgid != savegid)) ||
	    ((keys & F_MODE) && (*pmode != savemode)) || 
	    ((keys & F_FLAGS) && (*pflags != saveflags)) ||
	    first) {
		first = 0;
		if (flavor != F_NETBSD6 && dflag)
			printf("/set type=dir");
		else
			printf("/set type=file");
		if (keys & (F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(saveuid, 1)) != NULL)
				printf(" uname=%s", name);
			if (keys & F_UID || (keys & F_UNAME && name == NULL))
				printf(" uid=%lu", (u_long)saveuid);
		}
		if (keys & (F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(savegid, 1)) != NULL)
				printf(" gname=%s", name);
			if (keys & F_GID || (keys & F_GNAME && name == NULL))
				printf(" gid=%lu", (u_long)savegid);
		}
		if (keys & F_MODE)
			printf(" mode=%#lo", (u_long)savemode);
		if (keys & F_NLINK)
			printf(" nlink=1");
		if (keys & F_FLAGS) {
			char *str = flags_to_string(saveflags, "none");
			printf(" flags=%s", str);
			free(str);
		}
		printf("\n");
		*puid = saveuid;
		*pgid = savegid;
		*pmode = savemode;
		*pflags = saveflags;
	}
	return (0);
}
Exemple #8
0
/*
 * Display() takes a linked list of FTSENT structures and passes the list
 * along with any other necessary information to the print function.  P
 * points to the parent directory of the display list.
 */
static void
display(FTSENT *p, FTSENT *list)
{
	struct stat *sp;
	DISPLAY d;
	FTSENT *cur;
	NAMES *np;
	off_t maxsize;
	u_long maxlen, maxnlink;
	unsigned long long btotal, maxblock;
	ino_t maxinode;
	int bcfile, flen, glen, ulen, maxflags, maxgroup, maxuser;
	int entries, needstats;
	char *user, *group, buf[21];	/* 64 bits == 20 digits */
	char nuser[12], ngroup[12];
	char *flags = NULL;

	/*
	 * If list is NULL there are two possibilities: that the parent
	 * directory p has no children, or that fts_children() returned an
	 * error.  We ignore the error case since it will be replicated
	 * on the next call to fts_read() on the post-order visit to the
	 * directory p, and will be signalled in traverse().
	 */
	if (list == NULL)
		return;

	needstats = f_inode || f_longform || f_size;
	flen = 0;
	btotal = maxblock = maxinode = maxlen = maxnlink = 0;
	bcfile = 0;
	maxuser = maxgroup = maxflags = 0;
	maxsize = 0;
	for (cur = list, entries = 0; cur != NULL; cur = cur->fts_link) {
		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
			warnx("%s: %s",
			    cur->fts_name, strerror(cur->fts_errno));
			cur->fts_number = NO_PRINT;
			rval = 1;
			continue;
		}

		/*
		 * P is NULL if list is the argv list, to which different rules
		 * apply.
		 */
		if (p == NULL) {
			/* Directories will be displayed later. */
			if (cur->fts_info == FTS_D && !f_listdir) {
				cur->fts_number = NO_PRINT;
				continue;
			}
		} else {
			/* Only display dot file if -a/-A set. */
			if (cur->fts_name[0] == '.' && !f_listdot) {
				cur->fts_number = NO_PRINT;
				continue;
			}
		}
		if (cur->fts_namelen > maxlen)
			maxlen = cur->fts_namelen;
		if (needstats) {
			sp = cur->fts_statp;
			if (sp->st_blocks > maxblock)
				maxblock = sp->st_blocks;
			if (sp->st_ino > maxinode)
				maxinode = sp->st_ino;
			if (sp->st_nlink > maxnlink)
				maxnlink = sp->st_nlink;
			if (sp->st_size > maxsize)
				maxsize = sp->st_size;

			btotal += sp->st_blocks;
			if (f_longform) {
				if (f_numericonly) {
					snprintf(nuser, 12, "%u", sp->st_uid);
					snprintf(ngroup, 12, "%u", sp->st_gid);
					user = nuser;
					group = ngroup;
				} else {
					user = user_from_uid(sp->st_uid, 0);
					group = group_from_gid(sp->st_gid, 0);
				}
				if ((ulen = strlen(user)) > maxuser)
					maxuser = ulen;
				if ((glen = strlen(group)) > maxgroup)
					maxgroup = glen;
				if (f_flags) {
					flags = fflagstostr(sp->st_flags);
					if (*flags == '\0')
						flags = "-";
					if ((flen = strlen(flags)) > maxflags)
						maxflags = flen;
				} else
					flen = 0;

				if ((np = malloc(sizeof(NAMES) +
				    ulen + 1 + glen + 1 + flen + 1)) == NULL)
					err(1, NULL);

				np->user = &np->data[0];
				(void)strlcpy(np->user, user, ulen + 1);
				np->group = &np->data[ulen + 1];
				(void)strlcpy(np->group, group, glen + 1);

				if (S_ISCHR(sp->st_mode) ||
				    S_ISBLK(sp->st_mode))
					bcfile = 1;

				if (f_flags) {
					np->flags = &np->data[ulen + 1 + glen + 1];
				  	(void)strlcpy(np->flags, flags, flen + 1);
					if (*flags != '-')
						free(flags);
				}
				cur->fts_pointer = np;
			}
		}
		++entries;
	}

	if (!entries)
		return;

	d.list = list;
	d.entries = entries;
	d.maxlen = maxlen;
	if (needstats) {
		d.bcfile = bcfile;
		d.btotal = btotal;
		(void)snprintf(buf, sizeof(buf), "%llu", maxblock);
		d.s_block = strlen(buf);
		d.s_flags = maxflags;
		d.s_group = maxgroup;
		(void)snprintf(buf, sizeof(buf), "%llu",
		    (unsigned long long)maxinode);
		d.s_inode = strlen(buf);
		(void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
		d.s_nlink = strlen(buf);
		if (!f_humanval) {
			(void)snprintf(buf, sizeof(buf), "%lld",
				(long long) maxsize);
			d.s_size = strlen(buf);
		} else
			d.s_size = FMT_SCALED_STRSIZE-2; /* no - or '\0' */
		d.s_user = maxuser;
	}

	printfcn(&d);
	output = 1;

	if (f_longform)
		for (cur = list; cur != NULL; cur = cur->fts_link)
			free(cur->fts_pointer);
}
Exemple #9
0
/**
 * stat a file or directory and send its information to client.
 * 
 * @param name    The path to list
 * @param pclient data stream
 * @param verbose 1: LIST
 *                0: NLIST
 */
static void smbftpd_stat_filesystem(const char *name, FILE * pclient, int verbose)
{
	struct stat st;
	struct tm tmfile;
	char perm[11], timestr[13];
	char link_target[MAXPATHLEN + 5], tmp[MAXPATHLEN + 1];
#ifdef WITH_SSL
	char buf[MAXPATHLEN + 512];
#endif
	char convert_buf[MAXPATHLEN+1];
	int err;
	time_t t;

	if (lstat(name, (struct stat *) &st) < 0) {
		syslog(LOG_ERR, "%s (%d) Failed to lstat %s", __FILE__, __LINE__, name);
		return;
	}

	if (S_ISLNK(st.st_mode)) {
		if (smbftpd_conf.show_symlinks == 0) {
			return;
		}
		strcpy(perm, "lrwxrwxrwx");
		err = readlink(name, tmp, sizeof(tmp) - 1);
		if (err < 0) {
			syslog(LOG_ERR, "%s (%d) FTP readlink() error, error code:%d", 
				   __FILE__, __LINE__, errno);
			return;
		} else {
			tmp[err] = '\0';
		}

		snprintf(link_target, sizeof(link_target), " -> %s",
				 smbftpd_charset_fs2client(tmp, convert_buf, sizeof(convert_buf)));

	} else {
		strcpy(perm, "----------");
		if (S_ISDIR(st.st_mode))
			perm[0] = 'd';
		if (st.st_mode & S_IRUSR)
			perm[1] = 'r';
		if (st.st_mode & S_IWUSR)
			perm[2] = 'w';
		if (st.st_mode & S_IXUSR)
			perm[3] = 'x';
		if (st.st_mode & S_IRGRP)
			perm[4] = 'r';
		if (st.st_mode & S_IWGRP)
			perm[5] = 'w';
		if (st.st_mode & S_IXGRP)
			perm[6] = 'x';
		if (st.st_mode & S_IROTH)
			perm[7] = 'r';
		if (st.st_mode & S_IWOTH)
			perm[8] = 'w';
		if (st.st_mode & S_IXOTH)
			perm[9] = 'x';
		link_target[0] = '\0';		
	} 
	memcpy(&tmfile, localtime(&(st.st_mtime)), sizeof(struct tm));
	time(&t);
	if (tmfile.tm_year == localtime(&t)->tm_year){
		strncpy(timestr, ctime(&(st.st_mtime)) + 4, 12);
	} else {
		strftime(timestr, sizeof(timestr), "%b %d  %Y", &tmfile);
	}
	timestr[12]='\0';

	name = smbftpd_charset_fs2client(name, convert_buf, sizeof(convert_buf));

	if (verbose) {
#ifdef WITH_SSL
		if (pclient == stdout && smbftpd_session.ssl_ctrl.ssl_active_flag) {
			snprintf(buf, sizeof(buf), "%s %3s %-8s %-8s %12llu %s %s%s\r\n", 
					 perm, "1", user_from_uid(st.st_uid, 0), group_from_gid(st.st_gid, 0),
					 (unsigned long long) st.st_size,
					 timestr, name, link_target);
			ssl_write(ssl_con, buf, strlen(buf));
		} else if (smbftpd_session.ssl_ctrl.ssl_data_active_flag) {
			snprintf(buf, sizeof(buf), "%s %3s %-8s %-8s %12llu %s %s%s\r\n", 
					 perm, "1", user_from_uid(st.st_uid, 0), group_from_gid(st.st_gid, 0),
					 (unsigned long long) st.st_size,
					 timestr, name, link_target);
			ssl_write(ssl_data_con, buf, strlen(buf));
		} else
#endif
		fprintf(pclient, "%s %3s %-8s %-8s %12llu %s %s%s\r\n", perm, "1", 
				user_from_uid(st.st_uid, 0), group_from_gid(st.st_gid, 0),
				(unsigned long long) st.st_size,
				timestr, name, link_target);
	} else {
#ifdef WITH_SSL
		if (pclient == stdout && smbftpd_session.ssl_ctrl.ssl_active_flag) {
			snprintf(buf, sizeof(buf), "%s\r\n", name);
			ssl_write(ssl_con, buf, strlen(buf));
		} else if (smbftpd_session.ssl_ctrl.ssl_data_active_flag) {
			snprintf(buf, sizeof(buf), "%s\r\n", name);
			ssl_write(ssl_data_con, buf, strlen(buf));
		} else
#endif
		fprintf(pclient,"%s\r\n", name);
	}

	return;
}
Exemple #10
0
static void
statf(int indent, FTSENT *p)
{
	u_int32_t len, val;
	int fd, offset;
	const char *name = NULL;
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
	char *digestbuf;
#endif

	offset = printf("%*s%s%s", indent, "",
	    S_ISDIR(p->fts_statp->st_mode) ? "" : "    ", vispath(p->fts_name));

	if (offset > (INDENTNAMELEN + indent))
		offset = MAXLINELEN;
	else
		offset += printf("%*s", (INDENTNAMELEN + indent) - offset, "");

	if (!S_ISREG(p->fts_statp->st_mode) && (flavor == F_NETBSD6 || !dflag))
		output(indent, &offset, "type=%s",
		    inotype(p->fts_statp->st_mode));
	if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
		if (keys & F_UNAME &&
		    (name = user_from_uid(p->fts_statp->st_uid, 1)) != NULL)
			output(indent, &offset, "uname=%s", name);
		if (keys & F_UID || (keys & F_UNAME && name == NULL))
			output(indent, &offset, "uid=%u", p->fts_statp->st_uid);
	}
	if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
		if (keys & F_GNAME &&
		    (name = group_from_gid(p->fts_statp->st_gid, 1)) != NULL)
			output(indent, &offset, "gname=%s", name);
		if (keys & F_GID || (keys & F_GNAME && name == NULL))
			output(indent, &offset, "gid=%u", p->fts_statp->st_gid);
	}
	if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
		output(indent, &offset, "mode=%#o",
		    p->fts_statp->st_mode & MBITS);
	if (keys & F_DEV &&
	    (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
		output(indent, &offset, "device=%#jx",
		    (uintmax_t)p->fts_statp->st_rdev);
	if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
		output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink);
	if (keys & F_SIZE &&
	    (flavor == F_FREEBSD9 || S_ISREG(p->fts_statp->st_mode)))
		output(indent, &offset, "size=%ju",
		    (uintmax_t)p->fts_statp->st_size);
	if (keys & F_TIME)
#if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H)
		output(indent, &offset, "time=%jd.%09ld",
		    (intmax_t)p->fts_statp->st_mtimespec.tv_sec,
		    p->fts_statp->st_mtimespec.tv_nsec);
#else
		output(indent, &offset, "time=%jd.%09ld",
		    (intmax_t)p->fts_statp->st_mtime, (long)0);
#endif
	if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
		if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
		    crc(fd, &val, &len))
			mtree_err("%s: %s", p->fts_accpath, strerror(errno));
		close(fd);
		output(indent, &offset, "cksum=%lu", (long)val);
	}
#ifndef NO_MD5
	if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = MD5File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: MD5File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", MD5KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_MD5 */
#ifndef NO_RMD160
	if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = RMD160File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: RMD160File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", RMD160KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_RMD160 */
#ifndef NO_SHA1
	if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA1File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA1File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA1KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA1 */
#ifndef NO_SHA2
	if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA256_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA256_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA256KEY, digestbuf);
		free(digestbuf);
	}
#ifdef SHA384_BLOCK_LENGTH
	if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA384_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA384_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA384KEY, digestbuf);
		free(digestbuf);
	}
#endif
	if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
		if ((digestbuf = SHA512_File(p->fts_accpath, NULL)) == NULL)
			mtree_err("%s: SHA512_File failed: %s", p->fts_accpath,
			    strerror(errno));
		output(indent, &offset, "%s=%s", SHA512KEY, digestbuf);
		free(digestbuf);
	}
#endif	/* ! NO_SHA2 */
	if (keys & F_SLINK &&
	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
		output(indent, &offset, "link=%s",
		    vispath(rlink(p->fts_accpath)));
#if HAVE_STRUCT_STAT_ST_FLAGS
	if (keys & F_FLAGS && p->fts_statp->st_flags != flags) {
		char *str = flags_to_string(p->fts_statp->st_flags, "none");
		output(indent, &offset, "flags=%s", str);
		free(str);
	}
#endif
	putchar('\n');
}
/*
 * dump_nodes --
 *	dump the NODEs from `cur', based in the directory `dir'.
 *	if pathlast is none zero, print the path last, otherwise print
 *	it first.
 */
void
dump_nodes(const char *dir, NODE *root, int pathlast)
{
	NODE	*cur;
	char	path[MAXPATHLEN];
	const char *name;
	char	*str;
	char	*p, *q;

	for (cur = root; cur != NULL; cur = cur->next) {
		if (cur->type != F_DIR && !matchtags(cur))
			continue;

		if (snprintf(path, sizeof(path), "%s%s%s",
		    dir, *dir ? "/" : "", cur->name)
		    >= (int)sizeof(path))
			mtree_err("Pathname too long.");

		if (!pathlast)
			printf("%s", vispath(path));

#define MATCHFLAG(f)	((keys & (f)) && (cur->flags & (f)))
		if (MATCHFLAG(F_TYPE))
			appendfield(pathlast, "type=%s", nodetype(cur->type));
		if (MATCHFLAG(F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(cur->st_uid, 1)) != NULL)
				appendfield(pathlast, "uname=%s", name);
			else
				appendfield(pathlast, "uid=%u", cur->st_uid);
		}
		if (MATCHFLAG(F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(cur->st_gid, 1)) != NULL)
				appendfield(pathlast, "gname=%s", name);
			else
				appendfield(pathlast, "gid=%u", cur->st_gid);
		}
		if (MATCHFLAG(F_MODE))
			appendfield(pathlast, "mode=%#o", cur->st_mode);
		if (MATCHFLAG(F_DEV) &&
		    (cur->type == F_BLOCK || cur->type == F_CHAR))
			appendfield(pathlast, "device=%#jx",
			    (uintmax_t)cur->st_rdev);
		if (MATCHFLAG(F_NLINK))
			appendfield(pathlast, "nlink=%d", cur->st_nlink);
		if (MATCHFLAG(F_SLINK))
			appendfield(pathlast, "link=%s", vispath(cur->slink));
		if (MATCHFLAG(F_SIZE))
			appendfield(pathlast, "size=%ju",
			    (uintmax_t)cur->st_size);
		if (MATCHFLAG(F_TIME))
			appendfield(pathlast, "time=%jd.%09ld",
			    (intmax_t)cur->st_mtimespec.tv_sec,
			    cur->st_mtimespec.tv_nsec);
		if (MATCHFLAG(F_CKSUM))
			appendfield(pathlast, "cksum=%lu", cur->cksum);
		if (MATCHFLAG(F_MD5))
			appendfield(pathlast, "%s=%s", MD5KEY, cur->md5digest);
		if (MATCHFLAG(F_RMD160))
			appendfield(pathlast, "%s=%s", RMD160KEY,
			    cur->rmd160digest);
		if (MATCHFLAG(F_SHA1))
			appendfield(pathlast, "%s=%s", SHA1KEY,
			    cur->sha1digest);
		if (MATCHFLAG(F_SHA256))
			appendfield(pathlast, "%s=%s", SHA256KEY,
			    cur->sha256digest);
		if (MATCHFLAG(F_SHA384))
			appendfield(pathlast, "%s=%s", SHA384KEY,
			    cur->sha384digest);
		if (MATCHFLAG(F_SHA512))
			appendfield(pathlast, "%s=%s", SHA512KEY,
			    cur->sha512digest);
		if (MATCHFLAG(F_FLAGS)) {
			str = flags_to_string(cur->st_flags, "none");
			appendfield(pathlast, "flags=%s", str);
			free(str);
		}
		if (MATCHFLAG(F_IGN))
			appendfield(pathlast, "ignore");
		if (MATCHFLAG(F_OPT))
			appendfield(pathlast, "optional");
		if (MATCHFLAG(F_TAGS)) {
			/* don't output leading or trailing commas */
			p = cur->tags;
			while (*p == ',')
				p++;
			q = p + strlen(p);
			while(q > p && q[-1] == ',')
				q--;
			appendfield(pathlast, "tags=%.*s", (int)(q - p), p);
		}
		puts(pathlast ? vispath(path) : "");

		if (cur->child)
			dump_nodes(path, cur->child, pathlast);
	}
}
Exemple #12
0
/*
 * dump_nodes --
 *	dump the NODEs from `cur', based in the directory `dir'.
 *	if pathlast is none zero, print the path last, otherwise print
 *	it first.
 */
void
dump_nodes(const char *dir, NODE *root, int pathlast)
{
	NODE	*cur;
	char	path[MAXPATHLEN];
	const char *name;

	for (cur = root; cur != NULL; cur = cur->next) {
		if (cur->type != F_DIR && !matchtags(cur))
			continue;

		if (snprintf(path, sizeof(path), "%s%s%s",
		    dir, *dir ? "/" : "", cur->name)
		    >= sizeof(path))
			mtree_err("Pathname too long.");

		if (!pathlast)
			printf("%s ", vispath(path));

#define MATCHFLAG(f)	((keys & (f)) && (cur->flags & (f)))
		if (MATCHFLAG(F_TYPE))
			printf("type=%s ", nodetype(cur->type));
		if (MATCHFLAG(F_UID | F_UNAME)) {
			if (keys & F_UNAME &&
			    (name = user_from_uid(cur->st_uid, 1)) != NULL)
				printf("uname=%s ", name);
			else
				printf("uid=%u ", cur->st_uid);
		}
		if (MATCHFLAG(F_GID | F_GNAME)) {
			if (keys & F_GNAME &&
			    (name = group_from_gid(cur->st_gid, 1)) != NULL)
				printf("gname=%s ", name);
			else
				printf("gid=%u ", cur->st_gid);
		}
		if (MATCHFLAG(F_MODE))
			printf("mode=%#o ", cur->st_mode);
		if (MATCHFLAG(F_DEV) &&
		    (cur->type == F_BLOCK || cur->type == F_CHAR))
			printf("device=%#x ", cur->st_rdev);
		if (MATCHFLAG(F_NLINK))
			printf("nlink=%d ", cur->st_nlink);
		if (MATCHFLAG(F_SLINK))
			printf("link=%s ", cur->slink);
		if (MATCHFLAG(F_SIZE))
			printf("size=%lld ", (long long)cur->st_size);
		if (MATCHFLAG(F_TIME))
			printf("time=%ld.%ld ", (long)cur->st_mtimespec.tv_sec,
			    cur->st_mtimespec.tv_nsec);
		if (MATCHFLAG(F_CKSUM))
			printf("cksum=%lu ", cur->cksum);
		if (MATCHFLAG(F_MD5))
			printf("md5=%s ", cur->md5digest);
		if (MATCHFLAG(F_RMD160))
			printf("rmd160=%s ", cur->rmd160digest);
		if (MATCHFLAG(F_SHA1))
			printf("sha1=%s ", cur->sha1digest);
		if (MATCHFLAG(F_FLAGS))
			printf("flags=%s ",
			    flags_to_string(cur->st_flags, "none"));
		if (MATCHFLAG(F_IGN))
			printf("ignore ");
		if (MATCHFLAG(F_OPT))
			printf("optional ");
		if (MATCHFLAG(F_TAGS))
			printf("tags=%s ", cur->tags);
		puts(pathlast ? vispath(path) : "");

		if (cur->child)
			dump_nodes(path, cur->child, pathlast);
	}
}
Exemple #13
0
static int do_move( const char *from, const char *to ) {
	struct stat sb;
	int ask, ch, first;
	char modep[15];
	if ( !fflg && !access( to, F_OK ) ) {
		if ( lstat( from, &sb ) == -1 ) {
			warn( "%s", from );
			return ( 1 );
		}
#define YESNO "(y/n [n]) "
		ask = 0;
		if ( nflg ) {
			if ( vflg ) printf( "%s not overwritten\n", to );
			return ( 0 );
		} else if ( iflg ) {
			(void) fprintf( stderr, "overwrite %s? %s", to, YESNO );
			ask = 1;
		} else if ( access( to, W_OK ) && !stat( to, &sb ) && isatty( STDIN_FILENO ) ) {
			strmode( sb.st_mode, modep );
			(void) fprintf( stderr, "override %s%s%s/%s for %s? %s", modep + 1, modep[9] == ' ' ? "" : " ", user_from_uid( (unsigned long) sb.st_uid, 0 ), group_from_gid( (unsigned long) sb.st_gid, 0 ), to, YESNO );
			ask = 1;
		}
		if ( ask ) {
			first = ch = getchar();
			while ( ch != '\n' && ch != EOF )
				ch = getchar();
			if ( first != 'y' && first != 'Y' ) {
				(void) fprintf( stderr, "not overwritten\n" );
				return ( 0 );
			}
		}
	}
	if ( !rename( from, to ) ) {
		if ( vflg ) printf( "%s -> %s\n", from, to );
		return ( 0 );
	}
	if ( errno == EXDEV ) {
		struct statfs sfs;
		char path[PATH_MAX];
		if ( lstat( from, &sb ) == -1 ) {
			warn( "%s", from );
			return ( 1 );
		}
		if ( !S_ISLNK( sb.st_mode ) ) {
			if ( realpath( from, path ) == NULL ) {
				warn( "cannot resolve %s: %s", from, path );
				return ( 1 );
			}
			if ( !statfs( path, &sfs ) && !strcmp( path, sfs.f_mntonname ) ) {
				warnx( "cannot rename a mount point" );
				return ( 1 );
			}
		}
	} else {
		warn( "rename %s to %s", from, to );
		return ( 1 );
	}
	if ( lstat( from, &sb ) ) {
		warn( "%s", from );
		return ( 1 );
	}
	return ( S_ISREG( sb.st_mode ) ? fastcopy( from, to, &sb ) : copy( from, to ) );
}
static LONGEST
linux_xfer_osdata_sem (gdb_byte *readbuf,
		       ULONGEST offset, ULONGEST len)
{
  static const char *buf;
  static LONGEST len_avail = -1;
  static struct buffer buffer;

  if (offset == 0)
    {
      FILE *fp;
      
      if (len_avail != -1 && len_avail != 0)
	buffer_free (&buffer);
      len_avail = 0;
      buf = NULL;
      buffer_init (&buffer);
      buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");

      fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
      if (fp)
	{
	  char buf[8192];
	  
	  do
	    {
	      if (fgets (buf, sizeof (buf), fp))
		{
		  key_t key;
		  uid_t uid, cuid;
		  gid_t gid, cgid;
		  unsigned int perms, nsems;
		  int semid;
		  TIME_T otime, ctime;
		  int items_read;
		  
		  items_read = sscanf (buf,
				       "%d %d %o %u %d %d %d %d %lld %lld",
				       &key, &semid, &perms, &nsems,
				       &uid, &gid, &cuid, &cgid,
				       &otime, &ctime);
		  
		  if (items_read == 10)
		    {
		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
		      char otime_str[32], ctime_str[32];
		      
		      user_from_uid (user, sizeof (user), uid);
		      group_from_gid (group, sizeof (group), gid);
		      user_from_uid (cuser, sizeof (cuser), cuid);
		      group_from_gid (cgroup, sizeof (cgroup), cgid);
		      
		      time_from_time_t (otime_str, sizeof (otime_str), otime);
		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
		      
		      buffer_xml_printf (
			  &buffer,
			  "<item>"
			  "<column name=\"key\">%d</column>"
			  "<column name=\"semid\">%d</column>"
			  "<column name=\"permissions\">%o</column>"
			  "<column name=\"num semaphores\">%u</column>"
			  "<column name=\"user\">%s</column>"
			  "<column name=\"group\">%s</column>"
			  "<column name=\"creator user\">%s</column>"
			  "<column name=\"creator group\">%s</column>"
			  "<column name=\"last semop() time\">%s</column>"
			  "<column name=\"last semctl() time\">%s</column>"
			  "</item>",
			  key,
			  semid,
			  perms,
			  nsems,
			  user,
			  group,
			  cuser,
			  cgroup,
			  otime_str,
			  ctime_str);
		    }
		}
	    }
	  while (!feof (fp));

	  fclose (fp);
	}

      buffer_grow_str0 (&buffer, "</osdata>\n");
      buf = buffer_finish (&buffer);
      len_avail = strlen (buf);
    }

  if (offset >= len_avail)
    {
      /* Done.  Get rid of the buffer.  */
      buffer_free (&buffer);
      buf = NULL;
      len_avail = 0;
      return 0;
    }

  if (len > len_avail - offset)
    len = len_avail - offset;
  memcpy (readbuf, buf + offset, len);

  return len;
}
Exemple #15
0
int
ustar_wr(ARCHD *arcn)
{
	HD_USTAR *hd;
	char *pt, *name;
	char hdblk[sizeof(HD_USTAR)];

	/*
	 * check for those file system types ustar cannot store
	 */
	if (arcn->type == PAX_SCK) {
		paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name);
		return(1);
	}

	/*
	 * user asked that dirs not be written to the archive
	 */
	if (arcn->type == PAX_DIR && tar_nodir)
		return (1);

	/*
	 * check the length of the linkname
	 */
	if (PAX_IS_LINK(arcn->type) &&
	    ((size_t)arcn->ln_nlen > sizeof(hd->linkname))) {
		paxwarn(1, "Link name too long for ustar %s", arcn->ln_name);
		return(1);
	}

	/*
	 * split the path name into prefix and name fields (if needed). if
	 * pt != arcn->name, the name has to be split
	 */
	if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
		paxwarn(1, "File name too long for ustar %s", arcn->name);
		return(1);
	}

	/*
	 * zero out the header so we don't have to worry about zero fill below
	 */
	memset(hdblk, 0, sizeof(hdblk));
	hd = (HD_USTAR *)hdblk;
	arcn->pad = 0;

	/*
	 * split the name, or zero out the prefix
	 */
	if (pt != arcn->name) {
		/*
		 * name was split, pt points at the / where the split is to
		 * occur, we remove the / and copy the first part to the prefix
		 */
		*pt = '\0';
		fieldcpy(hd->prefix, sizeof(hd->prefix), arcn->name,
		    sizeof(arcn->name));
		*pt++ = '/';
	}

	/*
	 * copy the name part. this may be the whole path or the part after
	 * the prefix
	 */
	fieldcpy(hd->name, sizeof(hd->name), pt,
	    sizeof(arcn->name) - (pt - arcn->name));

	/*
	 * set the fields in the header that are type dependent
	 */
	switch (arcn->type) {
	case PAX_DIR:
		hd->typeflag = DIRTYPE;
		if (ul_oct(0, hd->size, sizeof(hd->size), 3))
			goto out;
		break;
	case PAX_CHR:
	case PAX_BLK:
		if (arcn->type == PAX_CHR)
			hd->typeflag = CHRTYPE;
		else
			hd->typeflag = BLKTYPE;
		if (ul_oct(MAJOR(arcn->sb.st_rdev), hd->devmajor,
		   sizeof(hd->devmajor), 3) ||
		   ul_oct(MINOR(arcn->sb.st_rdev), hd->devminor,
		   sizeof(hd->devminor), 3) ||
		   ul_oct(0, hd->size, sizeof(hd->size), 3))
			goto out;
		break;
	case PAX_FIF:
		hd->typeflag = FIFOTYPE;
		if (ul_oct(0, hd->size, sizeof(hd->size), 3))
			goto out;
		break;
	case PAX_SLK:
	case PAX_HLK:
	case PAX_HRG:
		if (arcn->type == PAX_SLK)
			hd->typeflag = SYMTYPE;
		else
			hd->typeflag = LNKTYPE;
		fieldcpy(hd->linkname, sizeof(hd->linkname), arcn->ln_name,
		    sizeof(arcn->ln_name));
		if (ul_oct(0, hd->size, sizeof(hd->size), 3))
			goto out;
		break;
	case PAX_REG:
	case PAX_CTG:
	default:
		/*
		 * file data with this type, set the padding
		 */
		if (arcn->type == PAX_CTG)
			hd->typeflag = CONTTYPE;
		else
			hd->typeflag = REGTYPE;
		arcn->pad = TAR_PAD(arcn->sb.st_size);
		if (ull_oct(arcn->sb.st_size, hd->size, sizeof(hd->size), 3)) {
			paxwarn(1, "File is too long for ustar %s",
			    arcn->org_name);
			return(1);
		}
		break;
	}

	strncpy(hd->magic, TMAGIC, TMAGLEN);
	strncpy(hd->version, TVERSION, TVERSLEN);

	/*
	 * set the remaining fields. Some versions want all 16 bits of mode
	 * we better humor them (they really do not meet spec though)....
	 */
	if (ul_oct(arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)) {
		if (uid_nobody == 0) {
			if (uid_name("nobody", &uid_nobody) == -1)
				goto out;
		}
		if (uid_warn != arcn->sb.st_uid) {
			uid_warn = arcn->sb.st_uid;
			paxwarn(1,
			    "Ustar header field is too small for uid %lu, "
			    "using nobody", (u_long)arcn->sb.st_uid);
		}
		if (ul_oct(uid_nobody, hd->uid, sizeof(hd->uid), 3))
			goto out;
	}
	if (ul_oct(arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) {
		if (gid_nobody == 0) {
			if (gid_name("nobody", &gid_nobody) == -1)
				goto out;
		}
		if (gid_warn != arcn->sb.st_gid) {
			gid_warn = arcn->sb.st_gid;
			paxwarn(1,
			    "Ustar header field is too small for gid %lu, "
			    "using nobody", (u_long)arcn->sb.st_gid);
		}
		if (ul_oct(gid_nobody, hd->gid, sizeof(hd->gid), 3))
			goto out;
	}
	if (ull_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime,
		sizeof(hd->mtime), 3) ||
	    ul_oct(arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3))
		goto out;
	if (!Nflag) {
		if ((name = user_from_uid(arcn->sb.st_uid, 1)) != NULL)
			strncpy(hd->uname, name, sizeof(hd->uname));
		if ((name = group_from_gid(arcn->sb.st_gid, 1)) != NULL)
			strncpy(hd->gname, name, sizeof(hd->gname));
	}

	/*
	 * calculate and store the checksum write the header to the archive
	 * return 0 tells the caller to now write the file data, 1 says no data
	 * needs to be written
	 */
	if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
	   sizeof(hd->chksum), 3))
		goto out;
	if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)
		return(-1);
	if (wr_skip(BLKMULT - sizeof(HD_USTAR)) < 0)
		return(-1);
	if (PAX_IS_REG(arcn->type))
		return(0);
	return(1);

    out:
	/*
	 * header field is out of range
	 */
	paxwarn(1, "Ustar header field is too small for %s", arcn->org_name);
	return(1);
}
static LONGEST
linux_xfer_osdata_msg (gdb_byte *readbuf,
		       ULONGEST offset, ULONGEST len)
{
  static const char *buf;
  static LONGEST len_avail = -1;
  static struct buffer buffer;

  if (offset == 0)
    {
      FILE *fp;
      
      if (len_avail != -1 && len_avail != 0)
	buffer_free (&buffer);
      len_avail = 0;
      buf = NULL;
      buffer_init (&buffer);
      buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
      
      fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
      if (fp)
	{
	  char buf[8192];
	  
	  do
	    {
	      if (fgets (buf, sizeof (buf), fp))
		{
		  key_t key;
		  PID_T lspid, lrpid;
		  uid_t uid, cuid;
		  gid_t gid, cgid;
		  unsigned int perms, cbytes, qnum;
		  int msqid;
		  TIME_T stime, rtime, ctime;
		  int items_read;
		  
		  items_read = sscanf (buf,
				       "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
				       &key, &msqid, &perms, &cbytes, &qnum,
				       &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
				       &stime, &rtime, &ctime);
		  
		  if (items_read == 14)
		    {
		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
		      char lscmd[32], lrcmd[32];
		      char stime_str[32], rtime_str[32], ctime_str[32];
		      
		      user_from_uid (user, sizeof (user), uid);
		      group_from_gid (group, sizeof (group), gid);
		      user_from_uid (cuser, sizeof (cuser), cuid);
		      group_from_gid (cgroup, sizeof (cgroup), cgid);
		      
		      command_from_pid (lscmd, sizeof (lscmd), lspid);
		      command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
		      
		      time_from_time_t (stime_str, sizeof (stime_str), stime);
		      time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
		      
		      buffer_xml_printf (
			  &buffer,
			  "<item>"
			  "<column name=\"key\">%d</column>"
			  "<column name=\"msqid\">%d</column>"
			  "<column name=\"permissions\">%o</column>"
			  "<column name=\"num used bytes\">%u</column>"
			  "<column name=\"num messages\">%u</column>"
			  "<column name=\"last msgsnd() command\">%s</column>"
			  "<column name=\"last msgrcv() command\">%s</column>"
			  "<column name=\"user\">%s</column>"
			  "<column name=\"group\">%s</column>"
			  "<column name=\"creator user\">%s</column>"
			  "<column name=\"creator group\">%s</column>"
			  "<column name=\"last msgsnd() time\">%s</column>"
			  "<column name=\"last msgrcv() time\">%s</column>"
			  "<column name=\"last msgctl() time\">%s</column>"
			  "</item>",
			  key,
			  msqid,
			  perms,
			  cbytes,
			  qnum,
			  lscmd,
			  lrcmd,
			  user,
			  group,
			  cuser,
			  cgroup,
			  stime_str,
			  rtime_str,
			  ctime_str);
		    }
		}
	    }
	  while (!feof (fp));

	  fclose (fp);
	}

      buffer_grow_str0 (&buffer, "</osdata>\n");
      buf = buffer_finish (&buffer);
      len_avail = strlen (buf);
    }

  if (offset >= len_avail)
    {
      /* Done.  Get rid of the buffer.  */
      buffer_free (&buffer);
      buf = NULL;
      len_avail = 0;
      return 0;
    }

  if (len > len_avail - offset)
    len = len_avail - offset;
  memcpy (readbuf, buf + offset, len);

  return len;
}
Exemple #17
0
static int
do_move(char *from, char *to)
{
	struct stat sb;
	char modep[15];

	/*
	 * (1)	If the destination path exists, the -f option is not specified
	 *	and either of the following conditions are true:
	 *
	 *	(a) The permissions of the destination path do not permit
	 *	    writing and the standard input is a terminal.
	 *	(b) The -i option is specified.
	 *
	 *	the mv utility shall write a prompt to standard error and
	 *	read a line from standard input.  If the response is not
	 *	affirmative, mv shall do nothing more with the current
	 *	source file...
	 */
	if (!fflg && !access(to, F_OK)) {
		int ask = 1;
		int ch;

		if (iflg) {
			if (access(from, F_OK)) {
				warn("rename %s", from);
				return (1);
			}
			(void)fprintf(stderr, "overwrite %s? ", to);
		} else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) {
			if (access(from, F_OK)) {
				warn("rename %s", from);
				return (1);
			}
			strmode(sb.st_mode, modep);
			(void)fprintf(stderr, "override %s%s%s/%s for %s? ",
			    modep + 1, modep[9] == ' ' ? "" : " ",
			    user_from_uid(sb.st_uid, 0),
			    group_from_gid(sb.st_gid, 0), to);
		} else
			ask = 0;
		if (ask) {
			if ((ch = getchar()) != EOF && ch != '\n') {
				int ch2;
				while ((ch2 = getchar()) != EOF && ch2 != '\n')
					continue;
			}
			if (ch != 'y' && ch != 'Y')
				return (0);
		}
	}

	/*
	 * (2)	If rename() succeeds, mv shall do nothing more with the
	 *	current source file.  If it fails for any other reason than
	 *	EXDEV, mv shall write a diagnostic message to the standard
	 *	error and do nothing more with the current source file.
	 *
	 * (3)	If the destination path exists, and it is a file of type
	 *	directory and source_file is not a file of type directory,
	 *	or it is a file not of type directory, and source file is
	 *	a file of type directory, mv shall write a diagnostic
	 *	message to standard error, and do nothing more with the
	 *	current source file...
	 */
	if (!rename(from, to)) {
		if (vflg)
			printf("%s -> %s\n", from, to);
		return (0);
	}

	if (errno != EXDEV) {
		warn("rename %s to %s", from, to);
		return (1);
	}

	/*
	 * (4)	If the destination path exists, mv shall attempt to remove it.
	 *	If this fails for any reason, mv shall write a diagnostic
	 *	message to the standard error and do nothing more with the
	 *	current source file...
	 */
	if (!lstat(to, &sb)) {
		if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) {
			warn("can't remove %s", to);
			return (1);
		}
	}

	/*
	 * (5)	The file hierarchy rooted in source_file shall be duplicated
	 *	as a file hierarchy rooted in the destination path...
	 */
	if (lstat(from, &sb)) {
		warn("%s", from);
		return (1);
	}

	return (S_ISREG(sb.st_mode) ?
	    fastcopy(from, to, &sb) : copy(from, to));
}
Exemple #18
0
static int
check(const char *path, const char *name, struct stat *sp)
{
	static int perm_answer = -1;
	struct choice {
		int ch;
		const char *str;
		int res;
		int perm;
	} *choice, choices[] = {
		{ 'y', "yes"   , 1, 0 },
		{ 'n', "no"    , 0, 0 },
		{ 'a', "always", 1, 1 },
		{ 'v', "never" , 0, 1 },
		{ 0, NULL, 0, 0 }
	};
	char modep[15], *flagsp;

	if (perm_answer != -1)
		return (perm_answer);

	/* Check -i first. */
	if (iflag)
		fprintf(stderr, "remove %s? ", path);
	else {
		/*
		 * If it's not a symbolic link and it's unwritable and we're
		 * talking to a terminal, ask.  Symbolic links are excluded
		 * because their permissions are meaningless.  Check stdin_ok
		 * first because we may not have stat'ed the file.
		 * Also skip this check if the -P option was specified because
	         * we will not be able to overwrite file contents and will
	         * barf later.
		 */
		if (!stdin_ok || S_ISLNK(sp->st_mode) || Pflag ||
		    (!access(name, W_OK) &&
		    !(sp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
		    (!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !uid)))
			return (1);
		strmode(sp->st_mode, modep);
		if ((flagsp = fflagstostr(sp->st_flags)) == NULL)
			err(1, NULL);
		fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ",
		    modep + 1, modep[9] == ' ' ? "" : " ",
		    user_from_uid(sp->st_uid, 0),
		    group_from_gid(sp->st_gid, 0),
		    *flagsp ? flagsp : "", *flagsp ? " " : "",
		    path);
		free(flagsp);
	}
	fflush(stderr);

	for (;;) {
		size_t len;
		char *answer;

		answer = fgetln(stdin, &len);
		/* clearerr(stdin); */
		if (answer == NULL)
			return (0);
		if (answer[len - 1] == '\n')
			len--;
		if (len == 0)
			continue;

		for (choice = choices; choice->str != NULL; choice++) {
			if (len == 1 && choice->ch == answer[0])
				goto valid_choice;
			if (strncasecmp(answer, choice->str, len) == 0)
				goto valid_choice;
		}

		fprintf(stderr, "invalid answer, try again (y/n/a/v): ");
	}

valid_choice:
	if (choice->perm)
		perm_answer = choice->res;
	return (choice->res);
}
Exemple #19
0
static void
statf(FTSENT *p)
{
	u_int32_t len, val;
	int fd, indent;
	const char *name;
#if !defined(NO_MD5) || !defined(NO_RMD160) || !defined(NO_SHA1) || !defined(NO_SHA2)
	char digestbuf[MAXHASHLEN + 1];
#endif

	indent = printf("%s%s",
	    S_ISDIR(p->fts_statp->st_mode) ? "" : "    ", vispath(p->fts_name));

	if (indent > INDENTNAMELEN)
		indent = MAXLINELEN;
	else
		indent += printf("%*s", INDENTNAMELEN - indent, "");

	if (!S_ISREG(p->fts_statp->st_mode))
		output(&indent, "type=%s", inotype(p->fts_statp->st_mode));
	if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
		if (keys & F_UNAME &&
		    (name = user_from_uid(p->fts_statp->st_uid, 1)) != NULL)
			output(&indent, "uname=%s", name);
		else /* if (keys & F_UID) */
			output(&indent, "uid=%u", p->fts_statp->st_uid);
	}
	if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
		if (keys & F_GNAME &&
		    (name = group_from_gid(p->fts_statp->st_gid, 1)) != NULL)
			output(&indent, "gname=%s", name);
		else /* if (keys & F_GID) */
			output(&indent, "gid=%u", p->fts_statp->st_gid);
	}
	if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
		output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS);
	if (keys & F_DEV &&
	    (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
		output(&indent, "device=%#x", p->fts_statp->st_rdev);
	if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
		output(&indent, "nlink=%u", p->fts_statp->st_nlink);
	if (keys & F_SIZE && S_ISREG(p->fts_statp->st_mode))
		output(&indent, "size=%lld", (long long)p->fts_statp->st_size);
#if defined(BSD4_4) && !defined(HAVE_NBTOOL_CONFIG_H)
	if (keys & F_TIME)
		output(&indent, "time=%ld.%ld",
		    (long)p->fts_statp->st_mtimespec.tv_sec,
		    p->fts_statp->st_mtimespec.tv_nsec);
#else
		output(&indent, "time=%ld.%ld",
		    p->fts_statp->st_mtime, 0);
#endif
	if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
		if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
		    crc(fd, &val, &len))
			mtree_err("%s: %s", p->fts_accpath, strerror(errno));
		close(fd);
		output(&indent, "cksum=%lu", (long)val);
	}
#ifndef NO_MD5
	if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
		if (MD5File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "MD5File");
		output(&indent, "md5=%s", digestbuf);
	}
#endif	/* ! NO_MD5 */
#ifndef NO_RMD160
	if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
		if (RMD160File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "RMD160File");
		output(&indent, "rmd160=%s", digestbuf);
	}
#endif	/* ! NO_RMD160 */
#ifndef NO_SHA1
	if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
		if (SHA1File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "SHA1File");
		output(&indent, "sha1=%s", digestbuf);
	}
#endif	/* ! NO_SHA1 */
#ifndef NO_SHA2
	if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
		if (SHA256_File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "SHA256_File");
		output(&indent, "sha256=%s", digestbuf);
	}
	if (keys & F_SHA384 && S_ISREG(p->fts_statp->st_mode)) {
		if (SHA384_File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "SHA384_File");
		output(&indent, "sha384=%s", digestbuf);
	}
	if (keys & F_SHA512 && S_ISREG(p->fts_statp->st_mode)) {
		if (SHA512_File(p->fts_accpath, digestbuf) == NULL)
			mtree_err("%s: %s", p->fts_accpath, "SHA512_File");
		output(&indent, "sha512=%s", digestbuf);
	}
#endif	/* ! NO_SHA2 */
	if (keys & F_SLINK &&
	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
		output(&indent, "link=%s", vispath(rlink(p->fts_accpath)));
#if HAVE_STRUCT_STAT_ST_FLAGS
	if (keys & F_FLAGS && p->fts_statp->st_flags != flags)
		output(&indent, "flags=%s",
		    flags_to_string(p->fts_statp->st_flags, "none"));
#endif
	putchar('\n');
}