pseudo: Add support for pseudo file symlinks

The pseudo format follows the standard definition, with the type "s"

Name s mode uid gid symlink

Will create the symlink "Name" with <gid> and <uid> and the contents
<symlink>.

Note <mode> is ignored, as symlinks always have "rwxrwxrwx" permissions.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index 13d60f7..d812af2 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -3581,6 +3581,12 @@
 				pseudo_ent->pathname, NULL,
 				lookup_inode2(&buf, PSEUDO_FILE_PROCESS,
 				pseudo_ent->dev->pseudo_id), dir);
+		} else if(pseudo_ent->dev->type == 's') {
+			add_dir_entry2(pseudo_ent->name, NULL,
+				pseudo_ent->pathname, NULL,
+				lookup_inode3(&buf, PSEUDO_FILE_OTHER, 0,
+				pseudo_ent->dev->symlink,
+				strlen(pseudo_ent->dev->symlink) + 1), dir);
 		} else {
 			add_dir_entry2(pseudo_ent->name, NULL,
 				pseudo_ent->pathname, NULL,
diff --git a/squashfs-tools/pseudo.c b/squashfs-tools/pseudo.c
index f85fe60..cbd45c7 100644
--- a/squashfs-tools/pseudo.c
+++ b/squashfs-tools/pseudo.c
@@ -387,6 +387,20 @@
 			goto error;
 		}	
 		break;
+	case 's':
+		if(def[0] == '\0') {
+			ERROR("Not enough arguments in symlink pseudo "
+				"definition \"%s\"\n", orig_def);
+			ERROR("Expected symlink\n");
+			goto error;
+		}
+
+		if(strlen(def) > 65535) {
+			ERROR("Symlink pseudo definition %s is greater than 65535"
+								" bytes!", def);
+			goto error;
+		}
+		break;
 	default:
 		ERROR("Unsupported type %c\n", type);
 		goto error;
@@ -443,6 +457,10 @@
 	case 'f':
 		mode |= S_IFREG;
 		break;
+	case 's':
+		/* permissions on symlinks are always rwxrwxrwx */
+		mode = 0777 | S_IFLNK;
+		break;
 	}
 
 	dev = malloc(sizeof(struct pseudo_dev));
@@ -459,6 +477,8 @@
 		dev->command = strdup(def);
 		add_pseudo_file(dev);
 	}
+	if(type == 's')
+		dev->symlink = strdup(def);
 
 	pseudo = add_pseudo(pseudo, dev, filename, filename);
 
@@ -472,6 +492,7 @@
 	ERROR("\tfilename b mode uid gid major minor\n");
 	ERROR("\tfilename c mode uid gid major minor\n");
 	ERROR("\tfilename f mode uid command\n");
+	ERROR("\tfilename s mode uid gid symlink\n");
 	free(filename);
 	return FALSE;
 }
diff --git a/squashfs-tools/pseudo.h b/squashfs-tools/pseudo.h
index c0d9f6f..ef693c3 100644
--- a/squashfs-tools/pseudo.h
+++ b/squashfs-tools/pseudo.h
@@ -31,7 +31,10 @@
 	unsigned int	major;
 	unsigned int	minor;
 	int		pseudo_id;
-	char		*command;
+	union {
+		char		*command;
+		char		*symlink;
+	};
 };
 
 struct pseudo_entry {