1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void error1(char *s)
{
write(2, s, strlen(s));
}
void error2(char *s1, char *s2)
{
error1(s1); error1(s2);
}
char buf[4096];
int main(int argc, char* argv[])
{
int fd, i;
ssize_t size;
char *s = buf + 5;
char *end = buf + sizeof(buf);
char *newargv[1003];
char *path;
int newargc = 0;
int noarg = 0;
if (argc < 2) {
error1("utf8script: too few arguments\n");
exit(1);
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror(argv[1]);
exit(1);
}
size = read(fd, buf, sizeof(buf));
if (size == -1) {
perror(argv[1]);
exit(1);
}
if (strncmp(buf, "\xef\xbb\xbf#!", 5) != 0) {
error2(argv[1], ": not a UTF-8 script\n");
exit(1);
}
if (argc > 1021) {
error1("utf8script: implementation limit: more than 1000 arguments\n");
exit(1);
}
/* new executable */
while (*s == ' ' && s != end) s++;
if (s == end) {
error2(argv[1], ": too many spaces\n");
exit(1);
}
newargv[newargc++] = path = s;
while (*s != ' ' && *s != '\n' && s < end)
s++;
if (s == end) {
error2(argv[1], ": script path too long\n");
exit(1);
}
if (*s == '\n')
noarg = 1;
*s++ = '\0';
/* optionally one argument */
if (!noarg) {
while (*s == ' ' && s < end) s++;
if (s == end) {
error2(argv[1], ": first line too long\n");
exit(1);
}
if (*s != '\n' && s != end) {
newargv[newargc++] = s;
while (*s != ' ' && *s != '\n' && s < end)
s++;
if (s == end) {
error2(argv[1], ": first line too long\n");
exit(1);
}
*s = '\0';
}
}
for (i = 1; i < argc; i++)
newargv[newargc++] = argv[i];
newargv[newargc++] = 0;
execv(path, newargv);
perror(path);
exit(1);
}
|