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

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