I am using two pipes to read from the stdout of the ftp program and write to the stdin of the ftp program. But the output part doesn't work well which i can't find out why. It looks like the stdout of the ftp bin won't immediately go through the pipe to the read side.Please help me exam my code ,thank you so much. And ,here is my code:
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <errno.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
typedef unsigned char UCHAR;
#define MAXBUFSIZE 1024
#define BUFSIZE 10240
typedef struct dev_info
{
UCHAR ip[4];
UCHAR id[16];
uint8_t state;
} dev_info;
char filename[64];
char fullname[128];
char ip_own[16]={0};
time_t timer;
struct tm *tblock;
char proname[256] = {0};
char buf_error[BUFSIZE]={0};
static char buf[BUFSIZE];
FILE *file_r, *file_w;
void erroroutput(char * str, const char * _func, const int _line)
{
memset(buf_error, 0x00, BUFSIZE);
sprintf(buf_error, "[%s:%d]%s: %s\n",_func, _line, str,strerror(errno));
printf("%s",buf_error);
}
int checkchar(char c)
{
if(c<=8)
return -1;
if((13<c)&(c<=31))
return -1;
if(c>=127)
return -1;
return 0;
}
pid_t rw_popen(char* cmd, FILE **rfile, FILE **wfile)
{
int pipefd[2],pipefd2[2];
pid_t pid;
short int flags=0;
if (pipe(pipefd) < 0)
{
erroroutput("pipe create error",__func__, __LINE__);
return -1;
}
if (pipe(pipefd2) < 0)
{
erroroutput("pipe create error",__func__, __LINE__);
return -1;
}
pid = fork();
if (pid < 0)
{
fprintf(stdout, "[%s:%d]fail to fork!\n",__func__, __LINE__);
return -1;
}
if (0 == pid)
{
close(pipefd[0]);
dup2(pipefd[1], 1);
close(pipefd[1]);
dup2(pipefd2[0], 0);
close(pipefd2[0]);
close(pipefd[1]);
char *argv[] = { "/bin/sh", "-c", cmd, NULL };
fprintf(stderr,"[%s:%d](pid):=%d\n",__func__, __LINE__,pid);
if (execvp("/bin/sh", argv) < 0)
{
fprintf(stderr, "[%s:%d]fail to execvp!\n",__func__, __LINE__);
exit(1);
}
fprintf(stderr, "[%s:%d]got here!\n",__func__, __LINE__);
exit(0);
}else
{
close(pipefd[1]);
*rfile = fdopen(pipefd[0], "r");
if(*rfile==NULL)
fprintf(stderr,"[%s:%d]*rfile==NULL\n",__func__, __LINE__);
close(pipefd2[0]);
*wfile = fdopen(pipefd2[1], "w");
if(*wfile==NULL)
fprintf(stderr,"[%s:%d]*wfile==NULL\n",__func__, __LINE__);
return pid;
}
}
void rw_pclose(pid_t pid, FILE *rfile, FILE *wfile) {
int status;
waitpid(pid, &status, 0);
fclose(rfile);
fclose(wfile);
}
int waitc(char cc, FILE ** file_rr, char* buff,uint16_t len,char* fc,...)
{
int c,i=0;
va_list argp;
int argnum = 0;
char *para[10];
va_start(argp, fc);
para[argnum]=fc;
argnum++;
while (1)
{
para[argnum] = va_arg(argp, char *);
if (strcmp(para[argnum],"") == 0)
break;
argnum++;
}
va_end(argp);
do
{
c=fgetc(*file_rr);
if(feof(*file_rr))
{
fprintf(stderr, "[%s:%d]Got eof!\n",__func__, __LINE__);
//return -1;
}
if(checkchar(c)<0)
break;/**/
putc(c,stdout);
buff[i]=c;
i++;
for(int k=0;k<argnum;k++)
{
if(strstr(buff,para[k])!=NULL)
{
fprintf(stderr, "[%s:%d]Fail ! %s%d\n",__func__, __LINE__,para[k],k);
return -1;
}
}
if(i>=len)
return -2;
}
while((char)c!=cc);
return 0;
}/**/
int loginftp(char* addr, char * user ,char * passw)
{
pid_t pid;
char cmd[256];
memset(cmd,0,sizeof(cmd));
strcat(cmd,"ftp ");
strcat(cmd,addr);
strcat(cmd,"\n");
fprintf(stderr, "[%s:%d]%s\n",__func__, __LINE__,cmd);
pid = rw_popen(cmd, &file_r, &file_w);
fprintf(stderr, "[%s:%d]pid=%d\n",__func__, __LINE__,pid);
if (pid)
{
fputs("anonymous\n",file_w);
fflush(file_w);
memset(buf,0,BUFSIZE);
waitc(':',&file_r,buf,BUFSIZE,"xxxxx","");
fputs("anonymous\n",file_w);
fflush(file_w);
memset(buf,0,BUFSIZE);
waitc(':',&file_r,buf,BUFSIZE,"xxxxx","");
fputs("quit\n",file_w);
fflush(file_w);
memset(buf,0,BUFSIZE);
waitc(':',&file_r,buf,BUFSIZE,"xxxxx","");
int c[2]={0};
c[0]=0x04;
fputc(c[0],file_w);
fflush(file_w);
//_rw_pclose2:
_rw_pclose1:
rw_pclose(pid, file_r, file_w);
}
fprintf(stderr, "[%s:%d]got here!\n",__func__, __LINE__);
return 0;
}
int main ( int argc, char * argv[] )
{
//strcpy(proname, argv[0]);
int ret;
ret=loginftp("ftp.sjtu.edu.cn","anonymous","anonymous");
fprintf(stderr, "[%s:%d]ret:%d\n",__func__, __LINE__,ret);
}
My makefile:
CC = gcc
LD = ld
AR = ar
RANLIB = ranlib
STRIP = strip
CFLAGS = -Wall -Wshadow -Wno-trigraphs -pipe
LDFLAGS = -lm -lpthread -g
BIN = unifyctrl
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
all: $(BIN)
$(OBJS): %.o: %.c
$(CC) -c -g $(CFLAGS) $< -o $@
$(BIN): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $(BIN)
$(STRIP) $(BIN)
clean:
rm -rf *.o
rm -rf $(BIN)
rm -rf *.o *.bak *.c.bak a
The first outcome of my code should be like this:
Connected to ftp-tel.sjtu.edu.cn.
220 (vsFTPd 3.0.2)
Name (ftp.sjtu.edu.cn:d01):
but i only got this :
Password: