亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tftpd.c

?? LinuxNetProgramming Linux網絡編程基礎實例
?? C
字號:
#include<sys/types.h>

#include<sys/ioctl.h>

#include<sys/stat.h>

#include<signal.h>

#include<fcntl.h>



#include<netinet/in.h>

#include<sys/socket.h>

#include<netinet/ip.h>

#include<arpa/tftp.h>

#include<netdb.h>



#include<stdlib.h>

#include<ctype.h>

#include<stdio.h>

#include<errno.h>

#include<syslog.h>

#include<string.h>

#include<setjmp.h>

#include<unistd.h>

#include<pwd.h>



#include "tftpdfunc.h"



#define TLMEOUT   4



struct transfer;

static void tftp(struct tftphdr*tp,int size);

static void snderr(int error);

static void sndfile(struct transfer *pf);

static void recvfile(struct transfer*pf);



static int check_file(const char*,int);



static struct sockaddr_in s_in={AF_INET};

static int peer;

static int rexmtval=TLMEOUT;

static int  maxtimeout=5*TLMEOUT;



#define PACKSIZE  BLOCKSIZE+4

static char buf[PACKSIZE];

static char ackbut[PACKSIZE];

static struct sockaddr_in from;

static size_t fromlen;

#define MAXARG  4

static char dirs[MAXARG+1];/*客戶可以訪問的目錄*/

int main(int argc,char**argv)

{

  struct tftphdr*tp;

  int n=0;

  int on=1;

  

  argc--;argv++;

  if(argc= =0)dirs[0]=″/tftpboot″; /*默認可訪問的目錄*/

  while(argc<0 && n<MAXARG)

    dirs[n++]=*argv++;

  openlog(″tftpd″,LOG_PID,LOG_DAEMON);

  

  if(IOCTL(0,FIONBIO,&on)<0){

    Syslog(LOG_ERR.″ioctl(FIONBIO):%m/n″);

    exit(1);

  }

  

  fromlen=sizeof(from);

  n=recvfrom(0,buf,sizeof (buf),0,

	     (struct sockaddr*)&from,&fromlen);

  if(n<0){

    syslog(LOG_ERR,″recvfrom:%m/n″);

    exit(1);

  }

  

  int pid;

  int i;

  size_t k;

  

  for(i=1;I<10;i++){

    pid=fork();

    if(pid<0){

      sleep(i);

      k=sizeof(from);

      i=recvfrom(0,buf ,sizeof(buf),0,

		 (struct sockaddr*)&from,&k);

      if(I>0){

	n=i;

	fromlen=k;

      }

    }else{/*如fork成功,則跳出for循環*/

      break;

    }

  }/*for*/

  if(pif<0){/*循環10次仍無法生成子進程,進程終止*/

    syslog(LOG_ERR,″fork :%m/n″);

    exit(1);

  }else if(pid!=0){

    exit(0);

  }



  if(!getuid()||!geteuid()){

    struct passwd *pwd=getpwnam(″nobody″);

    if(pwd)setuid(pwd->pw_uid);

    else setuid(32765);/*設置一較大的UID*/

  }



  from.sin_family=AF_INT;

  alarm(0);

  close(0);

  close(1);

  Peer=socket(AF_INET.SOCK_DGRAM,0);

  if(peer<0){

    syslog(LOG_ERR,″socket:%m/n″);

    exit(1);

  }

  if(bind(peer,(struct sockaddr*)&s_in,sizeof(s_in))<0){

    syslog(LOG_ERR,″bind:%m/n″);

    exit(1);

  }

  if(connect(peer,(struct sockaddr*)&from,sizef(from))<0) {

    syslog(LOG_ERR,″connect:%m/n″);

    exit(1);

  }



  Tp=(struct tftphdr*)buf;

  Tp-th_opcode=ntohs(tp-th_opcode);

  if(tp-th_opcode= =RRQ||tp->th_opcode= =WRQ) {

    tftp(tp,n);

    exit(1);

  }



  struct transfer{

    const char*f_mode;/*文件傳輸格式*/

    int(*f_validate)(const char,int);/*驗證函數*/

    void(*f_send)(struct transfer*);/*發送函數*/

    void(*f_recv)(struct transfer*);/*接收函數*/

  }transfer[]={

    {″netasci″,  check_file,   sndfile, recvfile,1},

    {″octet″,  check_file,  sndfile, recvfile,0},

    {0}

    /*最后一個元素值為0,以便于查接*/

  };



/*處理請求數據報*/

static void tftp(struct tftphdr*tp,int size)

{

  char*cp;

  int first=1,ecode;

  struct transfer*pf;

  char*filemane,*mode=NULL;

  

  filemane=cp=tp->th_stuff;

 again:

  while(cp<buf+size){

    if(*cp==′\0′)

      break;

    cp++;

  }

  if(*cp!= ′\0′){

    snderr(EBADOP);

    exit(1);

  }

  if(first){

    mode=++cp;

    first=0;

    goto again;

  }

  for(cp=mode;*cp;cp++)

    if(isupper(*cp)) {

      cp=tolower(*cp);

      

      for(pf=transfer;pf->f_mode;pf++)

	if(strcmp(pf->f_mode,mode)= =0)

	  break;

      if(pf->f_mode= =0){

	snderr(EBADOP);

	exit(1);

      }

      ecode=(*pf->f_validate)(filename,tp->th_opcode);

      if(ecode){

	snderr(ecode);

	exit(1);

      }/*ecode等于0,文件允許訪問*/

      if(tp->th_opcode= =WRQ)

	(*pf->f_recv)(pf);

      else

	(*pf->f_send)(pf);

      exit(0);

    }

}



  FILE*file;



static int check_file(const char*filename,int mode)

{

  struct stat stbuf;

  int fd;

  const char *cp;

  char **dirp;

  

  syslog(LOG_ERR,″tftpd:trying to get file:%s|n″,filename);

  

  if(*filename != ′/′){/*文件名不含絕對路徑*/

    syslog(LOG_ERR,″tftpd:serving file %s\n″,dirs[0]);

    chdir(dirs[0]);

  }else{

    for(dirp=dirs;*dirp;dirp++)

      if(strncmp(filename,*dirp,strlen(*dirp))==0)

	break;

    if(*dirp==0&&dirp!=dirs)

      return(EACCESS);

  }

/*文件名filename里包含有允許訪問的路徑*/

  if(!strncmp(filename,″../″,3))

    return EACCESS;

  for(cp=filename+1;*cp;cp++)

    if(*cp==′. ′&&strncmp(cp-1,″/../″,4)==0 )

      return(EACCESS);

  if(stat(filename,&stbuf)<0)

    return(errno==ENOENT?ENOTFOUND:EACCESS);

  if(mode==RRQ){

    if(stbuf.st_mode&(S_IREAD>>6)==0)

      return(EACCESS);

  }else{

    if((stbuf.st_mode&(S_IREAD>>6))==0)

      return(EACCESS);

  }

  fd=open(filename,mode==RRQ?0:1);

  if(fd<0)

    return(errno+100);

  file=fdopen(fd,(mode==RRQ)?″r″:″w″);

  if(file==NULL){

    return errno++100;

  }

  return(0);

}



int  timeout;

sigjmp_buf timeoutbuf;



static void timer(int signum)

{

  (void)signum;



  timeout += rexmtval;

  if(timeout>=naxtimeout)

    exit(1);

  siglongjmp(timeoutbuf,1);/*跳到斷點處執行*/

}



/*用于發送文件的函數*/

static void sndfile(struct transfer*pf)

{

  struct tftphdr*dp;

  struct tftphdr*ap;   /*ACK數據報報頭*/

  int block=1;

  int size, n;

  

  signal(SIGALRM,timer); /*設置定時器*/

  dp=read_init();  /*取得一塊緩沖區用于存放讀出的文件塊*/

  ap=(struct tftphdr*)ackbuf;

  do{

    size=my_read(file,*dp,pf->f_convert);/*讀文件塊到緩沖區里*/

    if(size<0){

      snderr(errno+100);

      goto abort;

    }

    dp->th_opcode=htons((u_short)DATA);

    dp->th_block=htons((u_short)block);

    timeout=-;

    (void)sigsetjmp(timeoutbuf,1); /*設置斷點*/

    

  send_data:

    if(send(peer,dp,size+4,0)!=size+4){

      syslog(LOG_ERR,″tftpd:write:%m\n″);

      goto abort;

    }

    read_block(file,pf->f_convert);

    for(;;){

      alarm(rexmtval);   /*啟動定時器*/

      n=recv(peer,ackbuf,sizeof(ackbuf),0);

      alarm(0); /*收到數據報,關閉定時器*/

      if(n<0){

	syslog(LOG_ERR,″tftpd:read:%m\n″);

	goto abort;

      }

      ap->th_opcode=ntohs(u_short)ap->th_opcode;

      ap->th_block=ntohs((u_short)ap->th_bolck);

      

      if(ap->th_opcode==ERROR)

	goto abort;

    

      if(ap->th_opcode==ACK){

	if(ap->th_block==block){

	  break;

	}

	/*同步*/

	(void)synch(peer);

	if(ap->th_block==(block-1)){

	  goto send_data; /*返回重發*/

	}

      }

      

    }/*for*/

    block++;

  }while (size==BLOCKSIZE);

  abort;

  (void )fclose(file);

}



Static void justquit(int signum)

{

  (void)signum;

  eixt(0);

}



/*接收文件*/

static void recvfile(struct transfer *pf)

{

  struct tftphdr *dp;

  struct tftphdr ap;  /*ACK緩沖區*/

  int block=0;

  int n, size;

  

  signal(SIGALRM,timer);

  dp=write_init();  /*取得一塊緩沖區用于存放接收到的文件塊*/

  ap=(struct tftphdr *)adkbuf;



  do{

    timeout=0;

    ap->th_opcode=htons(u_short)ACK;

    ap->th_block=htons((u_short)block);

    block++;

    (void)sigsetjmp(timeoutbuf,1);

    send_ack;

    if(send(peer,ackbuf,4,0)!=4){

      syslog(LOG_ERR,″tftpd:write:%m\n″);

      goto abort;

    }



    write_block(file,pf->f_convert);



    for(;;){

      alarm(rexmtval);

      n=recv(peer,dp,PACKSIZE,0); /*接收文件塊*/

      alarm(0);

      if(n<0)

	syslog(LOG_ERR,″tftpd:read:%m\n″);

      goto abort;

    }

    dp->th_opcode=ntohs(u_shot)dp->th_opcode;

    dp->th_block=ntohs(u_short)dp->th_block;

    if(dp->th_opcode==ERROR)

      goto abort;

    if(dp->th_opcode==DATA){

      if(dp->th_block==block){

	break;  /*normal*/

      }

      /*同步*/

      (void)synch(peer);

      if(dp->th_block==(block-1){

	goto send_ack;   /*重發*/

      }

	 size =my+write(file,&dp,n-4,pf->f_convert);

	 if(size!=(n-4))

	 if(size<0)

	 snderr(errno+100);

	 else snderr(ENOSPACE);

	 goto abort;

	 }

    }while(size==BLOCKSIZE);

    write_block(file,pf->f_convert);

    (void)fclose(file);   /*關閉文件*/

    

    ap->th_opcode=htons(u_short)ACK);

  ap->th_block=htons(u_short)(block);

  (void)send(peer,ackbuf,4,0);

  /*發送最后一個文件塊的ACK*/

  signal(SIGALRM,justquit);   /*設置定時器*/

  alarm(rexmtval);

  n=recv(peer,buf ,sizeof(buf),0);  /*超時將退出*/

  alarm(0);

  if(n>=4 &&dp->th_block){

    /*客戶端重發了最后一文件塊,南非要發ACK*/

    (void)send(peer,ackbuf,4,0);

  }

  abort;

  return;

}



struct errmsg{

  int e_code;

  const char*e_msg;

}errmsgs[]={

  {EUNDEF,   ″Undefined error code″},

  {ENOTFOUND,   ″File not found″},

  {EACCESS,  ″Access violation″},

  {ENOSPACE ,  ″Disk full or allocation exceeded″},

  {EBADOP,   ″Illegal TFTP operation″},

  {EBADID,   ″Unknown transfer ID″},

  {EEXISTS,   ″File already exists″},

  {ENOUSER,  ″No such user″},

  {-1,  0},

};



/*此函數用于發送一個ERROR數據報*/

static void snderr(int error)

{

  struct tftphdr*tp;

  int length;

  struct errmsg *pe;

  

  tp=(struct tftphdr*)buf;

  tp->th_opcode=htons(u_short)ERROR;

  tp->th_code=htons(u_short)error;

  for(pe=errmsgs;pe->e_code>=0;pe++)

    if(pe->e_code==error)/*該錯誤號已定義*/

      break;

  if(pe->e_code<0){

    pe->e_msg=strerror(error-100);

    tp->th_code=EUNDEF; /*置錯誤號為"UNDEF"*/

  }

  strcpy(tp->th_msg,pe-e_msg);

  length=strlen(pe->e_msg);

  tp->th_msg[length]= ′\0′;

  length +=5;

  if(send(peer,buf,length,0)!=length)

    syslog(LOG_ERR,″snderr:%m\n″);

}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品少妇一区二区三区日产乱码 | 国产精品99久久久久久久女警| 在线观看不卡一区| 一区二区在线观看av| 91日韩在线专区| 亚洲最新视频在线观看| 91福利在线免费观看| 亚洲成在线观看| 欧美一区二区在线播放| 精品一区二区三区的国产在线播放| 日韩精品一区二区三区老鸭窝| 秋霞午夜av一区二区三区| 欧美成人r级一区二区三区| 免费av成人在线| 精品国产一区二区精华| 国产成人精品1024| 亚洲欧洲成人自拍| 欧美日韩你懂的| 亚洲福中文字幕伊人影院| 8v天堂国产在线一区二区| 毛片不卡一区二区| 国产欧美精品一区二区三区四区| 成人福利视频网站| 亚洲午夜影视影院在线观看| 91精品国产综合久久精品麻豆| 精品无码三级在线观看视频| 欧美国产日韩亚洲一区| 在线观看日韩毛片| 久久er精品视频| 中文一区二区完整视频在线观看| 色综合天天综合网国产成人综合天| 亚洲午夜久久久| 亚洲精品在线观| 91麻豆高清视频| 青青草原综合久久大伊人精品优势| 久久久久久久网| 欧美性色欧美a在线播放| 免费成人结看片| 亚洲三级视频在线观看| 欧美一区二区视频观看视频| 风流少妇一区二区| 亚洲第一电影网| 国产亚洲欧美日韩俺去了| 在线视频国产一区| 国产尤物一区二区| 一区二区三区成人在线视频| 337p日本欧洲亚洲大胆精品 | 91色乱码一区二区三区| 美女精品自拍一二三四| 亚洲男同性恋视频| 久久亚洲精华国产精华液| 欧美在线免费视屏| 国产盗摄视频一区二区三区| 午夜亚洲福利老司机| 中文字幕欧美区| 日韩亚洲欧美一区二区三区| 色婷婷综合五月| 国产麻豆精品在线观看| 三级久久三级久久| 亚洲人成网站色在线观看| 久久这里只有精品6| 555www色欧美视频| 色婷婷久久久综合中文字幕| 国产一区二区视频在线播放| 日韩精品一卡二卡三卡四卡无卡| 亚洲欧美另类久久久精品2019| 久久精品欧美一区二区三区不卡| 91精品国产高清一区二区三区蜜臀 | 国产成人av电影在线| 日本美女一区二区三区视频| 洋洋av久久久久久久一区| 中文字幕欧美激情一区| 久久精品视频一区二区三区| 欧美白人最猛性xxxxx69交| 91精品国产高清一区二区三区 | 亚洲精品免费在线| 中文字幕在线观看不卡| 日本一区二区视频在线| 久久综合狠狠综合久久激情 | 久久久午夜电影| 精品成人a区在线观看| 91精品国产色综合久久不卡电影 | 99综合电影在线视频| 风流少妇一区二区| 成人av网站大全| 99riav久久精品riav| 99精品久久只有精品| 国产精品456| 国产.欧美.日韩| 成人黄色小视频| 91免费看视频| 91蝌蚪porny| 精品视频在线免费| 91精品一区二区三区久久久久久| 日韩一级片在线观看| 日韩免费看的电影| 久久综合九色综合久久久精品综合 | 日韩美女一区二区三区| 日韩精品一区二区在线观看| 日韩亚洲欧美一区| 久久精品一区二区三区av| 欧美极品另类videosde| 欧美国产精品一区二区三区| 亚洲婷婷在线视频| 亚洲国产视频a| 久久成人18免费观看| 成人一区二区三区| 色婷婷av一区二区三区gif| 欧美日韩久久不卡| 欧美v国产在线一区二区三区| 日本一区二区三区视频视频| 亚洲欧美国产毛片在线| 午夜日韩在线电影| 国产在线观看一区二区| 成人激情av网| 欧美精品xxxxbbbb| 久久久久久99精品| 依依成人综合视频| 麻豆国产精品官网| av在线免费不卡| 欧美日本一区二区在线观看| 久久精品一区二区三区不卡| 亚洲精品国产视频| 久久成人羞羞网站| 成人黄色片在线观看| 国产精品沙发午睡系列990531| 一区二区三区四区亚洲| 精品在线观看免费| 91黄视频在线观看| 久久蜜臀精品av| 性久久久久久久| 成人av先锋影音| 日韩一区二区免费在线观看| 中文字幕制服丝袜一区二区三区 | 色八戒一区二区三区| 91精品中文字幕一区二区三区| 中文一区二区在线观看| 日韩制服丝袜先锋影音| aaa欧美色吧激情视频| 欧美电视剧免费全集观看| 一区二区三区欧美久久| 国产成人精品三级| 欧美一区二区在线观看| 亚洲一区精品在线| 99久久精品免费看国产| 精品国产乱码久久久久久图片| 亚洲国产另类av| 91在线视频18| 国产精品久久久久久亚洲伦| 久久精品国产99国产| 欧美日韩一级二级| 亚洲女人的天堂| 成人app网站| 国产女主播视频一区二区| 九色综合国产一区二区三区| 欧美私模裸体表演在线观看| 亚洲色图丝袜美腿| 成人高清在线视频| 日本一区免费视频| 国产成人亚洲综合色影视| 精品国产一区二区三区久久影院| 天天色 色综合| 欧美美女激情18p| 亚洲图片自拍偷拍| 欧美日韩国产高清一区二区| 一区二区在线免费观看| 91传媒视频在线播放| 中文字幕制服丝袜一区二区三区 | 在线一区二区视频| 久久只精品国产| 免费高清在线一区| 欧美三电影在线| 曰韩精品一区二区| 成人国产精品免费观看视频| 中文无字幕一区二区三区| 国产一区二区三区四区五区美女| 91精品麻豆日日躁夜夜躁| 自拍偷拍国产亚洲| 懂色av一区二区在线播放| 中文字幕欧美日韩一区| av不卡在线播放| 一区二区三区免费在线观看| 色婷婷av一区二区三区gif | 亚洲日本在线a| www.欧美色图| 夜夜精品浪潮av一区二区三区 | 成人免费高清在线| 国产亚洲午夜高清国产拍精品 | 日韩av一级电影| 日韩一区和二区| 久久se精品一区二区| 精品欧美一区二区在线观看| 国产福利不卡视频| 国产嫩草影院久久久久| 不卡一区在线观看| 亚洲精品高清在线观看| 在线看不卡av| 日韩高清不卡在线| 91精品国产欧美一区二区18| 国产91清纯白嫩初高中在线观看 |