home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / net / unix / fileman.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-07  |  11.7 KB  |  511 lines

  1. #include "macs.hpp"
  2.  
  3. #include "fileman.hpp"
  4. #include "netface.hpp"
  5. #include "ghandler.hpp"
  6. #include "specache.hpp"
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13. #include <signal.h>
  14.  
  15. extern net_protocol *prot;
  16.  
  17.  
  18. #ifndef __WATCOMC__
  19. #include <sys/stat.h>
  20. #endif
  21.  
  22. file_manager *fman=NULL;
  23.  
  24. file_manager::file_manager(int argc, char **argv, net_protocol *proto) : proto(proto)
  25. {  
  26.   default_fs=NULL;
  27.   no_security=0;
  28.   nfs_list=NULL;
  29.  
  30.   int i;
  31.   for (i=1;i<argc;i++)
  32.     if (!strcmp(argv[i],"-bastard"))   // this bypasses filename security features
  33.     {
  34.       fprintf(stderr,"Warning : Security measures bypassed (-bastard)\n");
  35.       no_security=1;
  36.     }
  37. }
  38.  
  39.  
  40.  
  41. void file_manager::process_net()
  42. {
  43.   nfs_client *nc,*last=NULL;
  44.   for (nc=nfs_list;nc;)      // check for nfs request
  45.   {
  46.  
  47.     int ok=1;
  48.  
  49.     if (nc->sock->error())
  50.     {
  51.       ok=0;
  52.       //fprintf(stderr,"Killing nfs client, socket went bad\n");
  53.     } 
  54.     else if (nc->size_to_read && nc->sock->ready_to_write())
  55.       ok=nc->send_read();
  56.     else if (nc->sock->ready_to_read())
  57.       ok=process_nfs_command(nc);    // if we couldn't process the packeted, delete the connection
  58.     
  59.     if (ok)
  60.     {
  61.       last=nc;
  62.       nc=nc->next;
  63.     } else
  64.     {
  65.       if (last) last->next=nc->next;
  66.       else nfs_list=nc->next;
  67.       nfs_client *c=nc;
  68.       nc=nc->next;
  69.       delete c;
  70.     }
  71.   }
  72. }
  73.  
  74.  
  75. int file_manager::process_nfs_command(nfs_client *c)
  76. {
  77.   char cmd;
  78.   if (c->sock->read(&cmd,1)!=1) return 0;
  79.   switch (cmd)
  80.   {
  81.     case NFCMD_READ :
  82.     {
  83.       long size;
  84.       if (c->sock->read(&size,sizeof(size))!=sizeof(size)) return 0;
  85.       size=lltl(size);
  86.  
  87.       c->size_to_read=size;
  88.       return c->send_read();
  89.     } break;
  90.     case NFCMD_CLOSE :
  91.     {
  92.       return 0;
  93.     } break;
  94.     case NFCMD_SEEK :
  95.     {
  96.       long offset;
  97.       if (c->sock->read(&offset,sizeof(offset))!=sizeof(offset)) return 0;
  98.       offset=lltl(offset);
  99.       offset=lseek(c->file_fd,offset,0);
  100.       offset=lltl(offset);
  101.       if (c->sock->write(&offset,sizeof(offset))!=sizeof(offset)) return 0;
  102.       return 1;
  103.     } break;
  104.     case NFCMD_TELL :
  105.     {
  106.       long offset=lseek(c->file_fd,0,SEEK_CUR);
  107.       offset=lltl(offset);
  108.       if (c->sock->write(&offset,sizeof(offset))!=sizeof(offset)) return 0;
  109.       return 1;
  110.     } break;
  111.     
  112.     default :
  113.     { fprintf(stderr,"net driver : bad command from nfs client\n");
  114.       return 0;
  115.     }
  116.   } 
  117. }
  118.  
  119. int file_manager::nfs_client::send_read()   // return 0 if failure on socket, not failure to read
  120. {
  121.   if (file_fd>=0 && sock)
  122.   {
  123.     // first make sure the socket isn't 'full'
  124.     if (sock->ready_to_write())
  125.     {
  126.       char buf[READ_PACKET_SIZE];   
  127.       short read_total;
  128.       short actual;
  129.  
  130.       do
  131.       {      
  132.     read_total=size_to_read>(READ_PACKET_SIZE-2) ? (READ_PACKET_SIZE-2) : size_to_read;
  133.  
  134.     actual=read(file_fd,buf+2,read_total);
  135.     *((ushort *)buf)=lstl(actual);
  136.  
  137.     int write_amount=sock->write(buf,actual+2);
  138.     if (write_amount!=actual+2) 
  139.     { 
  140.       fprintf(stderr,"write failed\n");
  141.       return 0;
  142.     }
  143.  
  144.     size_to_read-=actual;
  145.  
  146.     if (!sock->ready_to_write())
  147.     {
  148.       sock->read_unselectable();
  149.       sock->write_selectable();
  150.       return 1;    // not ok to write anymore, try again latter
  151.     }
  152.  
  153.       } while (size_to_read && actual==read_total);
  154.  
  155.       sock->read_selectable();
  156.       sock->write_unselectable();
  157.  
  158.       size_to_read=0;
  159.       return 1;
  160.     } else 
  161.     {
  162.       sock->read_unselectable();
  163.       sock->write_selectable();
  164.       return 1;
  165.     }
  166.   }
  167.   return 0;
  168. }
  169.  
  170.  
  171. void file_manager::secure_filename(char *filename, char *mode)
  172. {
  173.   if (!no_security)
  174.   {    
  175.     if (filename[0]=='/') { filename[0]=0; return ; }
  176.     int level=0;
  177.     char *f=filename;
  178.     while (*f)
  179.     {
  180.       if (*f=='/') { f++; level++; }
  181.       else if (*f=='.' && f[1]=='.')
  182.       {
  183.     if (f[3]=='.') while (*f!='.') f++;
  184.     else
  185.     {
  186.       f+=2;
  187.       level--;
  188.     }
  189.       } else f++; 
  190.       
  191.     }
  192.     if (level<0)
  193.       filename[0]=0;
  194.   }
  195. }
  196.  
  197.  
  198.  
  199.  
  200. file_manager::nfs_client::nfs_client(net_socket *sock, int file_fd, nfs_client *next) : 
  201.   sock(sock),file_fd(file_fd),next(next),size_to_read(0)
  202.   sock->read_selectable();
  203. }  
  204.  
  205.  
  206. file_manager::nfs_client::~nfs_client() 
  207.   delete sock;
  208.   if (file_fd>=0)
  209.     close(file_fd);
  210. }
  211.  
  212.  
  213. void file_manager::add_nfs_client(net_socket *sock)
  214. {
  215.   uchar size[2];
  216.   char filename[300],mode[20],*mp;
  217.   if (sock->read(size,2)!=2) { delete sock; return ; }
  218.   if (sock->read(filename,size[0])!=size[0]) { delete sock; return ; }
  219.   if (sock->read(mode,size[1])!=size[1]) { delete sock; return ; }
  220.  
  221.  
  222.   secure_filename(filename,mode);  // make sure this filename isn't a security risk
  223.   if (filename[0]==0) { fprintf(stderr,"(denied)\n"); delete sock; return ; }
  224.  
  225.   mp=mode;
  226.   int flags=0;
  227.  
  228. #ifdef __WATCOMC__
  229.     flags|=O_BINARY;
  230. #endif
  231.  
  232.   while (*mp)
  233.   {
  234.     if (*mp=='w') flags|=O_CREAT|O_RDWR;
  235.     else if (*mp=='r') flags|=O_RDONLY;
  236.     mp++;
  237.   }
  238.       
  239.   int f=open(filename,flags,S_IRWXU | S_IRWXG | S_IRWXO);
  240.  
  241.   FILE *fp=fopen("open.log","ab"); 
  242.   fprintf(fp,"open file %s, fd=%d\n",filename,f);
  243.   fclose(fp);
  244.   
  245.   if (f<0) 
  246.     f=-1;  // make sure this is -1
  247.  
  248.  
  249.   long ret=lltl(f);
  250.   if (sock->write(&ret,sizeof(ret))!=sizeof(ret)) { delete sock; return ; }
  251.  
  252.   if (f<0)    // no file, sorry
  253.     delete sock;
  254.   else
  255.   {
  256.     long cur_pos=lseek(f,0,SEEK_CUR);
  257.     long size=lseek(f,0,SEEK_END);
  258.     lseek(f,cur_pos,SEEK_SET);
  259.     size=lltl(size);
  260.     if (sock->write(&size,sizeof(size))!=sizeof(size)) {  close(f); delete sock; sock=NULL; return ; }
  261.  
  262.     nfs_list=new nfs_client(sock,f,nfs_list);
  263.     nfs_list->size=size;
  264.   }
  265. }
  266.  
  267.  
  268.  
  269. void file_manager::remote_file::r_close(char *reason) 
  270. //  if (reason) fprintf(stderr,"remote_file : %s\n",reason);
  271.  
  272.   if (sock)
  273.   {
  274.     delete sock;
  275.     sock=NULL;
  276.   }
  277.  
  278. }
  279.  
  280. file_manager::remote_file::remote_file(net_socket *sock, char *filename, char *mode, remote_file *Next) : sock(sock)
  281. {
  282.   next=Next;
  283.   open_local=0;
  284.  
  285.   uchar sizes[3]={CLIENT_NFS,strlen(filename)+1,strlen(mode)+1};
  286.   if (sock->write(sizes,3)!=3) { r_close("could not send open info"); return ; }
  287.   if (sock->write(filename,sizes[1])!=sizes[1]) { r_close("could not send filename"); return ; }
  288.   if (sock->write(mode,sizes[2])!=sizes[2]) { r_close("could not send mode"); return ; }
  289.  
  290.   long remote_file_fd;
  291.   if (sock->read(&remote_file_fd,sizeof(remote_file_fd))!=sizeof(remote_file_fd)) 
  292.   { r_close("could not read remote fd"); return ; }   
  293.   remote_file_fd=lltl(remote_file_fd);
  294.   if (remote_file_fd<0) { r_close("remote fd is bad"); return ; }
  295.  
  296.   if (sock->read(&size,sizeof(size))!=sizeof(size)) { r_close("could not read remote filesize"); return ; } 
  297.  
  298.   size=lltl(size);
  299. }
  300.  
  301. int file_manager::remote_file::unbuffered_read(void *buffer, size_t count)
  302. {
  303.   if (sock && count)
  304.   {
  305.     uchar cmd=NFCMD_READ;
  306.     if (sock->write(&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("read : could not send command"); return 0; }
  307.  
  308.     long rsize=lltl(count);
  309.     if (sock->write(&rsize,sizeof(rsize))!=sizeof(rsize)) { r_close("read : could not send size"); return 0; }
  310.  
  311.     long total_read=0,total;
  312.     char buf[READ_PACKET_SIZE];
  313.     ushort size;
  314.  
  315.     ushort packet_size;    
  316.     do
  317.     {
  318.       if (sock->read(&packet_size,sizeof(packet_size))!=sizeof(packet_size)) 
  319.       {
  320.     fprintf(stderr,"could not read packet size\n");
  321.     return 0;
  322.       }
  323.  
  324.       packet_size=lstl(packet_size);
  325.  
  326.       ushort size_read=sock->read(buf,packet_size); 
  327.  
  328.       if (size_read!=packet_size) 
  329.       { 
  330.     if (sock->read(buf+2+size_read,packet_size-size_read)!=packet_size-size_read)
  331.     {
  332.       fprintf(stderr,"incomplete packet\n"); 
  333.       return 0; 
  334.     }
  335.       }
  336.  
  337.       memcpy(buffer,buf,packet_size);
  338.       buffer=(void *)(((char *)buffer)+packet_size);
  339.  
  340.       total_read+=packet_size;
  341.       count-=packet_size;
  342.     } while (packet_size==READ_PACKET_SIZE-2 && count);     
  343.     return total_read;
  344.   }
  345.   return 0;
  346. }
  347.  
  348. long file_manager::remote_file::unbuffered_tell()   // ask server where the offset of the file pointer is
  349. {
  350.   if (sock)
  351.   {
  352.     uchar cmd=NFCMD_TELL;
  353.     if (sock->write(&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("tell : could not send command"); return 0; }
  354.  
  355.     long offset;
  356.     if (sock->read(&offset,sizeof(offset))!=sizeof(offset)) { r_close("tell : could not read offset"); return 0; }    
  357.     return lltl(offset);
  358.   }    
  359.   return 0;
  360. }
  361.  
  362. long file_manager::remote_file::unbuffered_seek(long offset)  // tell server to seek to a spot in a file
  363. {
  364.   if (sock)
  365.   {
  366.     uchar cmd=NFCMD_SEEK;
  367.     if (sock->write(&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("seek : could not send command"); return 0; }
  368.  
  369.     long off=lltl(offset);
  370.     if (sock->write(&off,sizeof(off))!=sizeof(off)) { r_close("seek : could not send offset"); return 0; }
  371.  
  372.     if (sock->read(&offset,sizeof(offset))!=sizeof(offset)) { r_close("seek : could not read offset"); return 0; }    
  373.     return lltl(offset);
  374.   }    
  375.   return 0;
  376. }
  377.  
  378.  
  379. file_manager::remote_file::~remote_file()
  380. { r_close(NULL); }
  381.  
  382. int file_manager::rf_open_file(char *&filename, char *mode)
  383. {
  384.   net_address *fs_server_addr=NULL;
  385.  
  386.   if (filename[0]=='/' && filename[1]=='/')   // passive server file reference?
  387.   {
  388.     filename+=2;
  389.  
  390.     fs_server_addr=prot->get_node_address(filename,DEFAULT_COMM_PORT,0);
  391.     if (!fs_server_addr)
  392.     {
  393.       printf("couldn not get address for %s\n",filename);
  394.       return -1;
  395.     }
  396.   } else if (default_fs)
  397.     fs_server_addr=default_fs->copy();
  398.   
  399.   if (fs_server_addr)
  400.   {
  401.     net_socket *sock=proto->connect_to_server(fs_server_addr,net_socket::SOCKET_SECURE);
  402.     delete fs_server_addr;
  403.  
  404.     if (!sock)
  405.     { 
  406.       fprintf(stderr,"unable to connect\n");
  407.       return -1;
  408.     }
  409.  
  410.     remote_file *rf=new remote_file(sock,filename,mode,remote_list);
  411.     if (rf->open_failure())
  412.     {
  413.       delete rf;
  414.       return -1;
  415.     }
  416.     else 
  417.     {
  418.       remote_list=rf;
  419.       return rf->sock->get_fd();
  420.     }      
  421.   }
  422.  
  423.   secure_filename(filename,mode);
  424.   if (filename[0]==0) return -1;
  425.  
  426.   int flags=0;
  427.   while (*mode)
  428.   {
  429.     if (*mode=='w') flags|=O_CREAT|O_RDWR;
  430.     else if (*mode=='r') flags|=O_RDONLY;
  431.     mode++;
  432.   }
  433.  
  434.   char tmp_name[200];
  435.   if (get_filename_prefix() && filename[0] != '/')
  436.     sprintf(tmp_name,"%s%s",get_filename_prefix(),filename);
  437.   else strcpy(tmp_name,filename);
  438.  
  439.   int f=open(tmp_name,flags,S_IRWXU | S_IRWXG | S_IRWXO);
  440.   if (f>=0)
  441.   { close(f);
  442.     return -2;
  443.   }
  444.   
  445.   return -1;
  446. }
  447.  
  448.  
  449. file_manager::remote_file *file_manager::find_rf(int fd)
  450. {
  451.   remote_file *r=remote_list;
  452.   for (;r && r->sock->get_fd()!=fd;r=r->next)
  453.   {
  454.     if (r->sock->get_fd()==-1)
  455.     {
  456.       fprintf(stderr,"bad sock\n");
  457.     }
  458.   }
  459.   if (!r) { fprintf(stderr,"Bad fd for remote file %d\n",fd); }
  460.   return r;
  461. }
  462.  
  463.  
  464. long file_manager::rf_tell(int fd)
  465. {
  466.   remote_file *rf=find_rf(fd);
  467.   if (rf) return rf->unbuffered_tell();
  468.   else return 0;
  469. }
  470.  
  471. long file_manager::rf_seek(int fd, long offset)
  472. {
  473.   remote_file *rf=find_rf(fd);
  474.   if (rf) return rf->unbuffered_seek(offset);
  475.   else return 0;
  476. }
  477.  
  478. int file_manager::rf_read(int fd, void *buffer, size_t count)
  479. {
  480.   remote_file *rf=find_rf(fd);
  481.   if (rf) return rf->unbuffered_read(buffer,count);
  482.   else return 0;
  483. }
  484.  
  485. int file_manager::rf_close(int fd)
  486. {
  487.   remote_file *rf=remote_list,*last=NULL;
  488.   while (rf && rf->sock->get_fd()!=fd) rf=rf->next;
  489.   if (rf)
  490.   {
  491.     if (last) last->next=rf->next;
  492.     else remote_list=rf->next;
  493.     delete rf;
  494.     return 1;
  495.   } else 
  496.   {
  497.     fprintf(stderr,"Bad fd for remote file %d\n",fd); 
  498.     return 0;
  499.   }  
  500. }
  501.  
  502. long file_manager::rf_file_size(int fd)
  503. {
  504.   remote_file *rf=find_rf(fd);
  505.   if (rf) return rf->file_size();
  506.   else return 0;
  507. }
  508.