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

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

?? tftpd.c

?? 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一区二区三区免费野_久草精品视频
欧美精品一区二区三区四区| 欧美性色欧美a在线播放| 日韩美女一区二区三区四区| 欧美最猛黑人xxxxx猛交| 久久国产精品99久久人人澡| 国产精品一二三四区| 午夜欧美2019年伦理| 久久99精品国产麻豆不卡| 国产精品伊人色| 在线观看三级视频欧美| 欧美视频在线播放| 亚洲人成网站精品片在线观看| 亚洲综合精品久久| 久久超级碰视频| 99久久777色| 在线亚洲精品福利网址导航| 国产精品亚洲第一区在线暖暖韩国| 亚洲区小说区图片区qvod| 日韩亚洲电影在线| 91精品国产欧美一区二区18| 成人avav在线| 蜜桃av一区二区在线观看 | 中文字幕一区在线| 欧美午夜电影在线播放| 粉嫩一区二区三区性色av| 丝袜亚洲精品中文字幕一区| 国产精品久久久久影院亚瑟 | 欧美性猛片xxxx免费看久爱| 三级一区在线视频先锋 | 国产校园另类小说区| 麻豆精品视频在线观看视频| 亚洲国产aⅴ成人精品无吗| 国产精品夫妻自拍| 亚洲影视在线播放| 日日夜夜精品视频免费| 午夜成人免费电影| 日韩一区二区三区免费观看| 亚洲午夜精品在线| 欧美日韩国产一二三| 亚洲国产一区二区三区| 欧美日韩中字一区| 三级一区在线视频先锋| 欧美一区二区三区免费在线看| 亚洲123区在线观看| 欧美久久久久久蜜桃| 美女视频黄 久久| 国产女人18水真多18精品一级做| 亚洲成人久久影院| 成人三级伦理片| 欧美日韩日本视频| 亚洲gay无套男同| 成人免费毛片片v| 欧美成人精品福利| 国产精品久久久久久久久晋中| 国产精品高潮呻吟| 精品在线观看免费| 在线播放欧美女士性生活| 欧美激情一区二区三区在线| 久久99久久99| 日韩视频在线一区二区| 中文字幕日本乱码精品影院| 久久99久久99小草精品免视看| www.色精品| 日韩欧美成人激情| 国产精品久久久久久久久免费樱桃| 日韩国产在线一| 国产精品亲子伦对白| 毛片一区二区三区| 日韩av一级电影| 国产成人综合在线| 久久色视频免费观看| 久久精品国产色蜜蜜麻豆| 777奇米成人网| 精品一区二区精品| 欧美一区国产二区| 欧美一卡二卡在线| 在线不卡欧美精品一区二区三区| 成人免费黄色大片| 国产很黄免费观看久久| 经典三级一区二区| 久久99久久精品| 精品无人区卡一卡二卡三乱码免费卡| 亚洲h动漫在线| 韩国精品一区二区| 色婷婷狠狠综合| 欧美视频中文字幕| 在线一区二区视频| 欧美性猛交一区二区三区精品| 老司机一区二区| 精品国产乱子伦一区| 国产精品1区2区3区| 国产精品毛片久久久久久久| 色综合天天视频在线观看| 亚洲美女屁股眼交3| 91在线云播放| 日韩电影在线一区二区三区| 久久这里只有精品首页| 欧美日韩国产美| 久草这里只有精品视频| 亚洲h在线观看| 亚洲色图一区二区三区| 欧美日韩国产在线观看| 成人av中文字幕| 国产99久久久久久免费看农村| 亚洲女同一区二区| 欧美国产一区在线| 欧美日韩国产一级片| 日本精品一区二区三区高清| 91.com视频| 欧美日韩一区二区不卡| 一区二区三区 在线观看视频| 欧美精品一区视频| 国产在线精品一区二区不卡了 | 五月天视频一区| 国产欧美一区二区三区鸳鸯浴 | 国产一区999| 日本免费在线视频不卡一不卡二| 亚洲视频 欧洲视频| 亚洲色图视频网| 国产精品久久国产精麻豆99网站| 久久久久久久久久久久久夜| 日韩一区二区精品| 91精品国产色综合久久| 日韩欧美在线综合网| 精品视频123区在线观看| 91电影在线观看| 欧美一级搡bbbb搡bbbb| 欧美日韩综合不卡| 日韩免费性生活视频播放| 日韩精品一区二区在线| 久久看人人爽人人| 国产精品久久一级| 亚洲一区二区三区中文字幕| 亚洲成av人片一区二区三区| 亚洲成av人片一区二区| 国产一区二区视频在线| 国产精品一二三区在线| 91首页免费视频| 精品嫩草影院久久| 亚洲少妇30p| 狠狠色2019综合网| 波多野结衣中文字幕一区| 色播五月激情综合网| 91.xcao| 国产精品美女一区二区三区| 香蕉成人啪国产精品视频综合网| 久久国产综合精品| 欧美高清视频在线高清观看mv色露露十八 | 成人久久视频在线观看| 91在线精品一区二区| 日韩一区二区免费视频| 一区av在线播放| 99免费精品视频| 日本一区二区高清| 国产一区二区不卡| 2019国产精品| 日韩成人一级大片| 欧美女孩性生活视频| 一区二区欧美精品| 色先锋资源久久综合| 国产精品乱码一区二三区小蝌蚪| 精品午夜久久福利影院| 欧美少妇xxx| 偷拍亚洲欧洲综合| 精品国产3级a| 国产一区二区三区黄视频| 2024国产精品视频| 成人黄色一级视频| 中文字幕一区二区三区四区 | 久久99精品国产麻豆婷婷洗澡| 欧美美女直播网站| 日本亚洲天堂网| 日韩久久精品一区| 成人少妇影院yyyy| 日韩精品亚洲专区| 欧美一区二区三级| 国产酒店精品激情| 亚洲精品欧美综合四区| 在线免费观看日韩欧美| 日韩精品一二三| 日韩理论片中文av| 在线观看91精品国产麻豆| 国模娜娜一区二区三区| 亚洲色图20p| 日韩精品自拍偷拍| 在线视频国内自拍亚洲视频| 午夜亚洲福利老司机| 亚洲色图视频网| 久久精品亚洲一区二区三区浴池| 91成人免费在线| 成人av网在线| 成人一区二区在线观看| 日日夜夜免费精品| 一卡二卡欧美日韩| 国产精品色哟哟| 国产丝袜美腿一区二区三区| 欧美日韩国产首页| 欧美另类变人与禽xxxxx| 国产精品996| 国产suv精品一区二区883|