Я использую два канала для чтения из стандартного вывода программы ftp и записи в стандартный ввод программы ftp.Но выходная часть не работает, что я не могу понять, почему.Похоже, что стандартный вывод из ftp bin не будет сразу проходить через канал для чтения. Пожалуйста, помогите мне проверить мой код, большое спасибо.И вот мой код:
#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);
}
Мой make-файл:
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
Первый результат моего кода должен быть таким: Подключен к ftp-tel.sjtu.edu.cn,220 (vsFTPd 3.0.2) Имя (ftp.sjtu.edu.cn:d01): но я получил только это: Пароль: