home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / networking / tcpip / amitcp-support / ncftp-1.5.6 / src / amiga / s_socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-29  |  9.2 KB  |  605 lines

  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6.  
  7. #include <errno.h>
  8.  
  9. #include <sys/types.h>
  10. #include <netinet/in.h>
  11.  
  12. #ifdef __SASC
  13. #if 0
  14. #include <clib/socket_protos.h>
  15. #endif
  16. #include <pragmas/socket_pragmas.h>
  17. #include <proto/socket.h>
  18. #endif
  19.  
  20. #define PRIVATE_SOCKET_H
  21. #include "s_socket.h"
  22.  
  23. #define MAXFH S_MAXFH
  24.  
  25. /* FIXME: set atexit-handler for sockets too */
  26.  
  27. /* extern int SocketBase; */
  28.  
  29. static FILEEXT *files;
  30.  
  31. static void *zmalloc(size_t l)
  32. {
  33.     unsigned char *p = malloc(l);
  34.  
  35.     if(p)
  36.     memset(p, 0x00, l);
  37.  
  38.     return p;
  39. }
  40.  
  41. #define BUFSIZE 512
  42.  
  43. /*
  44.  does a FILE exists, which references fd ?
  45.  */
  46.  
  47. static int fd_has_refs(FILE *as, int fd)
  48. {
  49.     while(as)
  50.     {
  51.     if(fileno(as) == fd)
  52.         return 1;
  53.     as = as->_next;
  54.     }
  55.     return 0;
  56. }
  57.  
  58. static void s_fcloseall(void)
  59. {
  60.     while(files)
  61.     s_fclose(files);
  62. }
  63.  
  64. FILE *s_fdopen(int fd, const char *mode)
  65. {
  66.     FILEEXT *af;
  67.     unsigned char *buf;
  68.  
  69.     if(fd < MAXFH)
  70.     return fdopen(fd,mode);
  71.     else
  72.     {
  73.     af = zmalloc(sizeof(FILEEXT));
  74.     if(!af)
  75.         return NULL;
  76.     buf = zmalloc(BUFSIZE);
  77.     if(!buf)
  78.     {
  79.         free(af);
  80.         return NULL;
  81.     }
  82.     if(!strcmp(mode,"r"))
  83.     {
  84.         af->_flag = _IOREAD | _IOMYBUF;
  85.     }
  86.     else if(!strcmp(mode,"w"))
  87.     {
  88.         af->_flag = _IOWRT | _IOMYBUF;
  89.     }
  90.     else
  91.     {
  92.         fprintf(stderr,"s_fdopen: mode \"%s\" not supported\n", mode);
  93.  
  94.         free(af);
  95.         free(buf);
  96.         return 0;
  97.     }
  98.     
  99.     if(!files)
  100.         atexit(s_fcloseall);
  101.  
  102.     af->_next = files;
  103.     af->_ptr = buf;
  104.     af->_base = buf;
  105.     af->_size = BUFSIZE;
  106.     af->_flag |= _IOSOCK;
  107.     af->_file = fd;
  108.     files = af;
  109.  
  110.     return af;
  111.     }
  112. }
  113.  
  114. void s_fclose(FILE *af)
  115. {
  116.     FILE *pf = NULL, *sf = files;
  117.  
  118.     if(af->_file == 1)
  119.     {
  120.     fprintf(stderr,"s_fclose: someone tries to close stdout ;-(\n");
  121.     }
  122.  
  123.     if(!(af->_flag & _IOSOCK))
  124.     {
  125.     fclose(af);
  126.     }
  127.     else
  128.     {
  129.     if(af->_flag & _IOWRT)
  130.         s_fflush(af);
  131.  
  132.     while(sf && sf != af)
  133.     {
  134.         pf = sf;
  135.         sf = sf->_next;
  136.     }
  137.     if(sf)
  138.     {
  139.         if(pf)
  140.         pf->_next = sf->_next;
  141.         else
  142.         files = sf->_next;
  143. #if 1
  144.         if(! fd_has_refs(files, fileno(sf)))
  145.         s_close(fileno(sf)); /* FIXME: is this correct ? */
  146. #endif
  147.         free(sf->_base);
  148.         free(sf);
  149.     }
  150.     else
  151.     {
  152.         fprintf(stderr,"s_flose: illegal argument !!\n");
  153.     }
  154.     }
  155. }
  156.  
  157. size_t s_fread(void *b, size_t bsize, size_t n, FILE *fp)
  158. {
  159.     if(!(fp->_flag & _IOSOCK))
  160.     {
  161.     return fread(b, bsize, n, fp);
  162.     }
  163.     else
  164.     {
  165.     fprintf(stderr,"s_fread: not supported for sockets\n");
  166.     exit(20);
  167.     }
  168. }
  169. size_t s_fwrite(void *b, size_t bsize, size_t n, FILE *fp)
  170. {
  171.     if(!(fp->_flag & _IOSOCK))
  172.     {
  173.     return fwrite(b, bsize, n, fp);
  174.     }
  175.     else
  176.     {
  177.     fprintf(stderr,"s_ffwrite: not supported for sockets\n");
  178.     exit(20);
  179.     }
  180. }
  181.  
  182. static __inline int _s_fgetc(FILE *af)
  183. {
  184.     int n;
  185.  
  186.     if(af->_flag & _IOEOF)
  187.     {
  188.     return EOF;
  189.     }
  190.     if(--(af->_rcnt) >= 0)
  191.     {
  192.     return *(af->_ptr)++;
  193.     }
  194.     else
  195.     {
  196.     af->_ptr = af->_base;
  197.     n = s_recv(fileno(af), af->_base, af->_size, 0);
  198.     if(n > 0)
  199.     {
  200.         af->_rcnt = n-1;
  201.  
  202.         return *(af->_ptr)++;
  203.     }
  204.     else if(n == -1)
  205.     {
  206.         af->_flag |= _IOERR;
  207.         
  208.         return EOF;
  209.     }
  210.     else
  211.     {
  212.         af->_flag |= _IOEOF;
  213.  
  214.         return EOF;
  215.     }
  216.     }
  217. }
  218.  
  219. char *s_fgets(char *b, int bsize, FILE *af)
  220. {
  221.     char *p;
  222.     int c;
  223.  
  224.     if(!(af->_flag & _IOSOCK))
  225.     {
  226.     return fgets(b, bsize, af);
  227.     }
  228.     else
  229.     {
  230.     p = b;
  231.     if(!(af->_flag & _IOREAD))
  232.     {
  233.         fprintf(stderr,"s_fgets: illegal operation (read)\n");
  234.         errno = EBADF;
  235.         
  236.         return NULL;
  237.     }
  238.     while(bsize-- && ((c = _s_fgetc(af)) != EOF) && (c != '\n'))
  239.         *p++ = c; 
  240.     if(p==b)
  241.         return NULL;
  242.     if((c == EOF) && errno)
  243.         return NULL;
  244.     *p = '\0';
  245.     return b;
  246.     }
  247. }
  248.  
  249. int s_fputs(const char *b, FILE *fp)
  250. {
  251.     if(!(fp->_flag & _IOSOCK))
  252.     {
  253.     return fputs(b, fp);
  254.     }
  255.     else
  256.     {
  257.     fprintf(stderr,"s_fputs: not supported for sockets\n");
  258.     exit(20);
  259.     }
  260. }
  261.  
  262. int s_fseek(FILE *fp, long rpos, int mode)
  263. {
  264.     if(!(fp->_flag & _IOSOCK))
  265.     {
  266.     return fseek(fp, rpos, mode);
  267.     }
  268.     else
  269.     {
  270.     fprintf(stderr,"s_fseek: not supported for sockets\n");
  271.     exit(20);
  272.     }
  273. }
  274.  
  275.  
  276. int s_fgetc(FILE *af)
  277. {
  278.     if(!(af->_flag & _IOSOCK))
  279.     {
  280.     return fgetc(af);
  281.     }
  282.     else
  283.     {
  284.     if(!(af->_flag & _IOREAD))
  285.     {
  286.         fprintf(stderr,"s_fgetc: illegal operation (read)\n");
  287.         errno = EBADF;
  288.  
  289.         return EOF;
  290.     }
  291.     return _s_fgetc(af);
  292.     }
  293. }
  294.  
  295. int s_fflush(FILEEXT *af)
  296. {
  297.     int nbytes, RetVal;
  298.  
  299.     if(!(af->_flag & _IOSOCK))
  300.     {
  301.     return fflush(af);
  302.     }
  303.     else
  304.     {
  305.     if(!(af->_flag & _IOWRT))
  306.     {
  307.         fprintf(stderr,"s_fflush: illegal operation (not write)\n");
  308.         errno = EBADF;
  309.  
  310.         return EOF;
  311.     }
  312.     if(af->_wcnt)
  313.     {
  314.         nbytes = s_send(fileno(af), af->_base, af->_wcnt, 0);
  315.         if(nbytes != af->_wcnt)
  316.         {
  317.         af->_flag |= _IOERR;
  318.         RetVal = EOF;
  319.         }
  320.         else
  321.         RetVal = 0;
  322.  
  323.         af->_wcnt = 0;
  324.         af->_ptr = af->_base;
  325.     }
  326.     else
  327.         RetVal = 0;
  328.  
  329.     return RetVal;
  330.     }
  331. }
  332.  
  333. int s_vfprintf(FILE *af, const char *fmt, va_list args)
  334. {
  335.     int n;
  336.  
  337. /*     va_start(args, fmt);*/
  338.     
  339.     /* if buffer gets exceeded, we loose */
  340.  
  341.     if(!(af->_flag & _IOSOCK))
  342.     {
  343.     n = vfprintf(af, (char *) fmt, args);
  344.     }
  345.     else
  346.     {
  347.     s_fflush(af);
  348.     n = af->_wcnt = vsprintf(af->_ptr, fmt, args);
  349.     af->_ptr += n;
  350.     if(n > af->_size)
  351.     {
  352.         fprintf(stderr,"vfprintf: file buf exceeded\n");
  353.         exit(20);
  354.     }
  355.     }
  356.     va_end(args);
  357.  
  358.     return n;
  359. }
  360.  
  361. int s_fprintf(FILEEXT *af, const char *fmt, ...)
  362. {
  363.     int n;
  364.     va_list args;
  365.  
  366.     va_start(args, fmt);
  367.     
  368.     /* if buffer gets exceeded, we loose */
  369.  
  370.     if(!(af->_flag & _IOSOCK))
  371.     {
  372.     n = vfprintf(af, (char *) fmt, args);
  373.     }
  374.     else
  375.     {
  376.     s_fflush(af);
  377.     n = af->_wcnt = vsprintf(af->_ptr, fmt, (va_list) args);
  378.     af->_ptr += n;
  379.     if(n > af->_size)
  380.     {
  381.         fprintf(stderr,"fprintf: file buf exceeded\n");
  382.         exit(20);
  383.     }
  384.     }
  385.     va_end(args);
  386.  
  387.     return n;
  388. }
  389.  
  390. int s_fputc(int c, FILEEXT *af)
  391. {
  392.     int success;
  393.  
  394.     if(!(af->_flag & _IOSOCK))
  395.     {
  396.     return fputc(c, af);
  397.     }
  398.     else
  399.     {
  400.     if(!(af->_flag & _IOWRT))
  401.     {
  402.         fprintf(stderr,"s_fflush: illegal operation (write)\n");
  403.         errno = EBADF;
  404.  
  405.         return -1;
  406.     }
  407.     if(af->_wcnt > af->_size)
  408.     {
  409.         success = s_fflush(af);
  410.     }
  411.     (af->_wcnt)++;
  412.     *(af->_ptr)++ = c;
  413.  
  414.     return success ? success : c;
  415.     }
  416. }
  417.  
  418. int s_ferror(FILE *af)
  419. {
  420.     if(!(af->_flag & _IOSOCK))
  421.     {
  422.     return ferror(af);
  423.     }
  424.     else
  425.     {
  426.     return 0;        /* FIXME */
  427.     }
  428. }
  429.  
  430. int s_read(int fh, void *buf, unsigned int len)
  431. {
  432.     if(fh < MAXFH)
  433.     return read(fh, buf, len);
  434.     else
  435.     return recv(fh-MAXFH, buf, len, 0);
  436. }
  437.  
  438. int s_write(int fh, void *buf, unsigned int len)
  439. {
  440.     if(fh < MAXFH)
  441.     return write(fh, buf, len);
  442.     else
  443.     return send(fh-MAXFH, buf, len, 0);
  444. }
  445.  
  446.  
  447. int s_close(int sd)
  448. {
  449.     int RetVal;
  450.  
  451.     if(sd == 1)
  452.     {
  453.     fprintf(stderr,"s_close: someone tries to close stdout ;-(\n");
  454.     }
  455.     if(sd < MAXFH)
  456.     return close(sd);
  457.     else
  458.     {
  459. #if 0
  460.     fprintf(stderr,"s_close(%d)\n", sd -S_MAXFH);
  461. #endif
  462.     RetVal = CloseSocket(sd - MAXFH);
  463. #if 0
  464.     if(RetVal)
  465.     {
  466.         perror("s_close failed\n");
  467.     }
  468. #endif
  469.     }
  470.     return RetVal;
  471. }
  472.  
  473. int s_isatty(int sd)
  474. {
  475.     if(sd < MAXFH)
  476.     return isatty(sd);
  477.     else
  478.     {
  479.     return 0;
  480.     }
  481. }
  482.  
  483. int s_iomode(int sd, int mode)
  484. {
  485.     if(sd < MAXFH)
  486.     return isatty(sd);
  487.     else
  488.     {
  489.     return 1; /* not a level 1 file FIXME: call for sockets available? */
  490.     }
  491. }
  492.  
  493. long s_lseek(int sd, long a, int mode)
  494. {
  495.     if(sd < MAXFH)
  496.     return lseek(sd, a, mode);
  497.     else
  498.     {
  499.     fprintf(stderr,"s_lseek: not supported for sockets\n");
  500.     exit(20);
  501.     }
  502. }
  503.  
  504.  
  505. long s_accept(long s, struct sockaddr *addr, int *addrlen)
  506. {
  507.     int ns;
  508.  
  509.     ns = accept(s-S_MAXFH, addr, (long *) addrlen);
  510.     if(ns>=0)
  511.     ns += S_MAXFH;
  512.     return ns;
  513. }
  514.  
  515. long s_bind(long s, struct sockaddr *name, long namelen)
  516. {
  517.     return bind(s-S_MAXFH, name, namelen);
  518. }
  519.  
  520. long s_CloseSocket(long sd)
  521. {
  522.     return CloseSocket(sd-S_MAXFH);
  523. }
  524.  
  525. long s_connect(long s, struct sockaddr *name, long namelen)
  526. {
  527.     return connect(s-S_MAXFH, name, namelen);
  528. }
  529.  
  530. long s_getpeername(long s, struct sockaddr *name, int *namelen)
  531. {
  532.     return getpeername(s-S_MAXFH, name, (long *) namelen);
  533. }
  534.  
  535. long s_getsockname(long s, struct sockaddr *name, int *namelen)
  536. {
  537.     return getsockname(s-S_MAXFH, name, (long *) namelen);
  538. }
  539.  
  540. long s_setsockopt(long s, long level, long optname, caddr_t optval, long optlen)
  541. {
  542.     return setsockopt(s-S_MAXFH, level, optname, optval, optlen);
  543.  
  544. long s_listen(long s, long backlog)
  545. {
  546.     return listen(s-S_MAXFH, backlog);
  547. }
  548.  
  549. long s_recv(long s, char *buf, long len, long flags)
  550. {
  551.     int n;
  552.  
  553.     n = recv(s-S_MAXFH, buf, len, flags);
  554. #if 0
  555.     if(n != -1)
  556.     {
  557.     fprintf(stderr,"s_recv = ");
  558.     write(2, buf, n);
  559.     fprintf(stderr,"\n");
  560.     }
  561.     else
  562.     {
  563.     fprintf(stderr,"recv returned -1\n");
  564.     }
  565. #endif
  566.     return n;
  567. }
  568.  
  569. long s_recvfrom(long s, char *buf, long len, long flags, 
  570.         struct sockaddr *from, long *len2)
  571. {
  572.     int n;
  573.  
  574.     n = recvfrom(s-S_MAXFH, buf, len, flags, from, len2);
  575.     return n;
  576. }
  577.  
  578. long s_select(long nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
  579.           struct timeval *timeout)
  580. {
  581.     return select(nfds, readfds, writefds, exceptfds, timeout);
  582. }
  583.  
  584. int s_send(int s, char *msg, int len, int flags)
  585. {
  586.     return send(s-S_MAXFH, msg, len, flags);
  587. }
  588.  
  589. long s_shutdown(long s, long how)
  590. {
  591.     return shutdown(s-S_MAXFH, how);
  592. }
  593.  
  594. long s_socket(long domain, long type, long protocol)
  595. {
  596.     int s;
  597.     
  598.     s = socket(domain, type, protocol);
  599.     if(s>=0)
  600.     s += S_MAXFH;
  601.  
  602.     return s;
  603. }
  604.