mars-nwe/opt/unxcomm.c

137 lines
3.2 KiB
C

/* unxcomm.c 22-Oct-98
* simple UNX program to work together with 'comm'
* to demonstrate usage of pipefilesystem
* needs mars_nwe version >= 0.99.pl13 !
* comm and unxcomm must be same version !
* 'run' directory must exist and must have
* read and write permission for every user.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
static char **build_argv(int bufsize, char *command, int len)
/* routine returns **argv for use with execv routines */
{
int offset = ((len+4) / 4) * 4; /* aligned offset for **argv */
int components = (bufsize - offset) / 4;
if (components-- > 1) { /* minimal argv[0] + NULL */
char **argv = (char **)(command+offset);
char **pp = argv;
char *p = command;
char c;
int i=0;
*pp = p;
*(p+len) = 0;
while ((0 != (c = *p++)) && i < components) {
if (c == 10 || c == 13) {
*(p-1) = '\0';
break;
} else if (c == 32 || c == '\t') {
*(p-1) = '\0';
if (*p != 32 && *p != '\t' && *p != 10 && *p != 13) {
*(++pp)=p;
i++;
}
} else if (!i && c == '/') { /* here i must get argv[0] */
*pp=p;
}
}
if (*pp && !**pp) *pp=NULL;
else
*(++pp)=NULL;
return(argv);
}
return(NULL);
}
#define MAXARGLEN 1024
int bl_read(int fd, void *buf, int size)
{
fd_set fdin;
struct timeval t;
int result;
FD_ZERO(&fdin);
FD_SET(fd, &fdin);
t.tv_sec = 1;
t.tv_usec = 0;
result = select(fd+1, &fdin, NULL, NULL, &t);
if (result > 0)
result=read(fd, buf, size);
return(result);
}
int main(int argc, char *argv[])
{
int size=-1;
int pid=getpid();
char buf[MAXARGLEN+1024];
char fifopath[257];
char *p;
close(2);
dup2(1,2);
if (argc > 3) {
strcpy(fifopath, argv[0]);
p=strrchr(fifopath, '/');
if (p) {
++p;
sprintf(p, "run/%08x.in", pid);
if (mkfifo(fifopath, 0600)) {
perror("mkfifo");
fprintf(stderr, "unxcomm:fifo.in=`%s`\n", fifopath);
} else {
fprintf(stdout, "#%08x\n", pid);
fflush(stdout);
size=0;
}
}
}
if (!size) {
int tries=0;
int fd = open(fifopath, O_RDONLY);
if (fd > -1) {
while (tries++ < 5) {
int l;
while (0 < (l=bl_read(fd, buf+size, MAXARGLEN-size))) {
size+=l;
}
if (size && buf[size-1] == '\0') break;
}
close(fd);
} else {
perror("open fifo");
size=-1;
}
unlink(fifopath);
}
if ( 0 < size) {
char **argvv=build_argv(sizeof(buf), buf, size);
if (argvv) {
char path[300];
execv(buf, argvv);
sprintf(path, "/usr/bin/%s", *argvv);
execv(path, argvv);
sprintf(path, "/bin/%s", *argvv);
execv(path, argvv);
sprintf(path, "/usr/sbin/%s", *argvv);
execv(path, argvv);
sprintf(path, "/sbin/%s", *argvv);
execv(path, argvv);
fprintf(stderr, "%s:\tCould not find program '%s'\n", *argv, buf);
exit(1);
}
}
fprintf(stderr, "%s:\tGot no paras\n", *argv);
exit(1);
}