home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / tcp / Networking / TCP / Server / wu-ftpd / src / amitcp.c < prev    next >
C/C++ Source or Header  |  1994-09-15  |  4KB  |  196 lines

  1. /*
  2.  * This module contains __open() and fstat() from AmiTCP 3.0 beta 2
  3.  * which will be recompiled with our redefined getumask(), geteuid()
  4.  * and getegid() functions from config.h so that we don't need to open
  5.  * usergroup.library if multiuser.library is installed.
  6.  *
  7.  * Author is Jarno Rajahalme <Jarno.Rajahalme@hut.fi>.
  8.  *
  9.  * Copyright © 1993,1994 AmiTCP/IP Group, <amitcp-group@hut.fi>
  10.  *             Helsinki University of Technology, Finland.
  11.  *             All rights reserved.
  12.  */
  13.  
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <stdarg.h>
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <dos.h>
  20. #include <ios1.h>
  21. #include <unistd.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <sys/socket.h>
  25. #include <proto/dos.h>
  26. #include <proto/utility.h>
  27. #include <bsdsocket.h>
  28.  
  29. #include "AmiTCP:src/netlib/netlib.h"
  30. #include "AmiTCP:src/netlib/fibex.h"
  31.  
  32. #include "config.h"
  33.  
  34. int fstat(int fd, struct stat *st)
  35. {
  36.   struct UFB *ufb = chkufb(fd);
  37.  
  38.   if (st == NULL || ((1 & (long)st) == 1)) {
  39.     errno = EFAULT;
  40.     return -1;
  41.   }
  42.  
  43.   if (ufb == NULL || ufb->ufbflg == 0) {
  44.     errno = EBADF;
  45.     return -1;
  46.   }
  47.  
  48.   if (ufb->ufbflg & UFB_SOCK) { /* a socket */
  49.     long value;
  50.     long size = sizeof(value);
  51.     bzero(st, sizeof(*st));
  52.  
  53.     /* st->st_dev = ??? */
  54.     st->st_mode = S_IFSOCK | S_IRUSR | S_IWUSR;
  55.     st->st_uid = geteuid();
  56.     st->st_gid = getegid();
  57.  
  58.     if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &size) == 0)
  59.       st->st_blksize = value;
  60.  
  61.     return 0;
  62.   } else { /* ordinal file */
  63.     if (ExamineFH(ufb->ufbfh, __dostat_fib)) {
  64.       __dostat(__dostat_fib, st);
  65.       st->st_dev = (dev_t)((struct FileHandle *)BADDR(ufb->ufbfh))->fh_Type;
  66.       return 0;
  67.     } else {
  68.       errno = EIO;
  69.       return -1;
  70.     }
  71.   }
  72. }
  73.  
  74. extern int (*__closefunc)(int);
  75.  
  76. __stdargs int
  77. __open(const char *name, int mode, ...)
  78. {
  79.   struct UFB *ufb;
  80.   int         fd;
  81.   int         flags;
  82.   char        newfile = TRUE;
  83.   BPTR        file;
  84.  
  85.   /*
  86.    * Set up __closefunc (which is used at cleanup)
  87.    */
  88.   __closefunc = __close;
  89.  
  90.   /*
  91.    * Check for the break signals
  92.    */
  93.   __chkabort();
  94.  
  95.   /*
  96.    * find first free ufb
  97.    */
  98.   ufb = __allocufb(&fd);
  99.   if (ufb == NULL)
  100.     return -1; /* errno is set by the __allocufb() */
  101.  
  102.   /*
  103.    * malloc space for the name & copy it
  104.    */
  105.   if ((ufb->ufbfn = malloc(strlen(name)+1)) == NULL) {
  106.     SET_OSERR(ERROR_NO_FREE_STORE);
  107.     errno = ENOMEM;
  108.     return -1;
  109.   }
  110.   strcpy(ufb->ufbfn, name);
  111.   /*
  112.    * Translate mode to ufb flags
  113.    */
  114.   switch (mode & (O_WRONLY | O_RDWR)) {
  115.   case O_RDONLY:
  116.     if (mode & (O_APPEND | O_CREAT | O_TRUNC | O_EXCL)) {
  117.       errno = EINVAL;
  118.       return -1;
  119.     }
  120.     flags = UFB_RA;
  121.     break;
  122.   case O_WRONLY:
  123.     flags = UFB_WA;
  124.     break;
  125.   case O_RDWR:
  126.     flags = UFB_RA | UFB_WA;
  127.     break;
  128.   default:
  129.     errno = EINVAL;
  130.     return -1;
  131.   }
  132.   if (mode & O_APPEND)
  133.     flags |= UFB_APP;
  134.   if (mode & O_XLATE)
  135.     flags |= UFB_XLAT;
  136.   if (mode & O_TEMP)
  137.     flags |= UFB_TEMP;
  138.   if (mode & O_CREAT) {
  139.     BPTR lock;
  140.     if (lock = Lock((char *)name, SHARED_LOCK)) {
  141.       if (mode & O_EXCL) {
  142.     UnLock(lock);
  143.     errno = EEXIST;
  144.     free(ufb->ufbfn);
  145.     return -1;
  146.       }
  147.  
  148.       if (mode & O_TRUNC)
  149.     newfile = FALSE;
  150.       else
  151.     mode &= ~O_CREAT;
  152.  
  153.       UnLock(lock);
  154.     }
  155.   }
  156.   if (mode & O_CREAT) {
  157.     if ((file = Open((char *)name, MODE_NEWFILE)) == NULL)
  158.       goto osfail;
  159.  
  160.     if (newfile) {
  161.       va_list va;
  162.       int cmode;
  163.  
  164.       va_start(va, mode);
  165.  
  166.       cmode = va_arg(va, int) & ~getumask();
  167.       
  168.       chmod((char *)name, cmode); /* hope this doesn't fail :-) */
  169.     }
  170.   }
  171.   else {
  172.     if ((file = Open((char *)name,
  173.              (flags & UFB_WA && mode & O_LOCK) ? 
  174.              MODE_READWRITE : MODE_OLDFILE)) == NULL)
  175.       goto osfail;
  176.   }
  177.  
  178.   /*
  179.    * All done! Setting the ufb->ufbflg field to non-zero value marks
  180.    * this ufb used. 
  181.    */
  182.   ufb->ufbflg = flags;
  183.   ufb->ufbfh = (long)file;
  184.  
  185.   return fd;
  186.  
  187. osfail:
  188.   {
  189.     int code = IoErr();
  190.     if (ufb->ufbfn)
  191.       free(ufb->ufbfn);
  192.     set_errno(code);
  193.   }
  194.   return -1;
  195. }
  196.