From 253b6e965c4a01e0165aa6aafcbb268ad12f1678 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Wed, 7 Nov 2012 11:06:56 +0100 Subject: [PATCH] mkfs: symlink support . mkproto too --- man/man1/mkfs.mfs.1 | 4 ++-- usr.sbin/mkfs.mfs/mkfs.c | 22 ++++++++++++++++++++-- usr.sbin/mkproto/mkproto.c | 13 ++++++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/man/man1/mkfs.mfs.1 b/man/man1/mkfs.mfs.1 index 2b2361739..4fb69b100 100644 --- a/man/man1/mkfs.mfs.1 +++ b/man/man1/mkfs.mfs.1 @@ -89,8 +89,8 @@ The first entry on each line (except the first 3 and the $ lines, which terminate directories) is the name the file or directory will get on the new file system. Next comes its mode, with the first character being -\fB\-dbc\fR for regular files, directories, block special files and character -special files, respectively. +\fB\-dbcs\fR for regular files, directories, block special files and character +special files, symlinks, respectively. The next two characters are used to specify the SETUID and SETGID bits, as shown above. The last three characters of the mode are the diff --git a/usr.sbin/mkfs.mfs/mkfs.c b/usr.sbin/mkfs.mfs/mkfs.c index 1cbc761b7..5bfdd344b 100644 --- a/usr.sbin/mkfs.mfs/mkfs.c +++ b/usr.sbin/mkfs.mfs/mkfs.c @@ -479,6 +479,8 @@ void sizeup_dir() sizeup_dir(); } else if (*p == 'b' || *p == 'c') { + } else if (*p == 's') { + zonecount++; /* Symlink contents is always stored a block */ } else { if ((f = fopen(token[4], "r")) == NULL) { fprintf(stderr, "%s: Can't open %s: %s\n", @@ -690,6 +692,21 @@ ino_t inode; incr_link(inode); } +void enter_symlink(ino_t inode, char *link) +{ + zone_t z; + char *buf; + + buf = alloc_block(); + z = alloc_zone(); + strcpy(buf, link); + put_block((z << zone_shift), buf); + + add_zone(inode, z, (size_t) strlen(link), current_time); + + free(buf); +} + /*================================================================ * eat_dir - recursively install directory @@ -738,6 +755,8 @@ ino_t parent; if (token[6]) size = atoi(token[6]); size = block_size * size; add_zone(n, (zone_t) (makedev(maj,min)), size, current_time); + } else if (*p == 's') { + enter_symlink(n, token[4]); } else { /* Regular file. Go read it. */ if ((f = open(token[4], O_RDONLY)) < 0) { @@ -781,8 +800,6 @@ int f; free(buf); } - - /*================================================================ * directory & inode management assist group *===============================================================*/ @@ -1151,6 +1168,7 @@ char *p; if (c1 == 'd') mode |= S_IFDIR; if (c1 == 'b') mode |= S_IFBLK; if (c1 == 'c') mode |= S_IFCHR; + if (c1 == 's') mode |= S_IFLNK; if (c1 == '-') mode |= S_IFREG; if (c2 == 'u') mode |= S_ISUID; if (c3 == 'g') mode |= S_ISGID; diff --git a/usr.sbin/mkproto/mkproto.c b/usr.sbin/mkproto/mkproto.c index 26b1ad368..3f4cc99b1 100644 --- a/usr.sbin/mkproto/mkproto.c +++ b/usr.sbin/mkproto/mkproto.c @@ -155,7 +155,7 @@ char *dirname; count++; strcpy(tempend, name); - if (stat(temp, &st) == -1) { + if (lstat(temp, &st) == -1) { fprintf(stderr, "cant get status of '%s' \n", temp); continue; } @@ -189,6 +189,16 @@ char *dirname; fprintf(outfile, "\n"); continue; } + if (mode == S_IFLNK) { + char linkcontent[PATH_MAX]; + memset(linkcontent, 0, sizeof(linkcontent)); + if(readlink(temp, linkcontent, sizeof(linkcontent)) < 0) { + perror("readlink"); + exit(1); + } + fprintf(outfile, "%s%s\n", indentstr, linkcontent); + continue; + } fprintf(outfile, " /dev/null"); fprintf(stderr,"File\n\t%s\n has an invalid mode, made empty.\n",temp); } @@ -217,6 +227,7 @@ struct stat *st; (st->st_mode & S_IFMT) == S_IFDIR ? 'd' : (st->st_mode & S_IFMT) == S_IFCHR ? 'c' : (st->st_mode & S_IFMT) == S_IFBLK ? 'b' : + (st->st_mode & S_IFMT) == S_IFLNK ? 's' : '-', /* file type */ (st->st_mode & S_ISUID) ? 'u' : '-', /* set uid */ (st->st_mode & S_ISGID) ? 'g' : '-', /* set gid */ -- 2.44.0