sco.c
上传用户:zibowangxu
上传日期:2007-01-04
资源大小:331k
文件大小:19k
源码类别:

Ftp客户端

开发平台:

Unix_Linux

  1. /****************************************************************************  
  2.  
  3.   Copyright (c) 1999 WU-FTPD Development Group.  
  4.   All rights reserved.
  5.   
  6.   Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
  7.     The Regents of the University of California.
  8.   Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
  9.   Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
  10.   Portions Copyright (c) 1989 Massachusetts Institute of Technology.
  11.   Portions Copyright (c) 1998 Sendmail, Inc.
  12.   Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman.
  13.   Portions Copyright (c) 1997 by Stan Barber.
  14.   Portions Copyright (c) 1997 by Kent Landfield.
  15.   Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
  16.     Free Software Foundation, Inc.  
  17.  
  18.   Use and distribution of this software and its source code are governed 
  19.   by the terms and conditions of the WU-FTPD Software License ("LICENSE").
  20.  
  21.   If you did not receive a copy of the license, it may be obtained online
  22.   at http://www.wu-ftpd.org/license.html.
  23.  
  24.   $Id: sco.c,v 1.6 1999/08/27 14:18:42 wuftpd Exp $
  25.  
  26. ****************************************************************************/
  27. #ifndef _SCO_DS /* none of this is required on SCO OpenServer 5 */
  28. /* Written in 1992, 1993 by Eduard Vopicka, Prague University of Economics */
  29. #include "../src/config.h"
  30. #include <sys/types.h>
  31. #include <stdio.h>
  32. #include <fcntl.h>
  33. #include <sys/immu.h>
  34. #include <sys/dir.h> /* required by <sys/user.h> */
  35. #include <sys/user.h>
  36. #include <sys/signal.h>
  37. #include <sys/fs/s5param.h>
  38. #include <string.h>
  39. #include <syslog.h>
  40. #include <sys/stat.h>
  41. #include <varargs.h>
  42. static int KmemFd = -1;
  43. kmem_open()
  44. {
  45.     if (KmemFd < 0 && (KmemFd = open("/dev/kmem", O_RDWR, 0)) < 0) {
  46. syslog(LOG_EMERG, "kmem open failed: %m");
  47. exit(1);
  48.     }
  49. }
  50. int wrub(addr, off, len)
  51.      char *addr;
  52.      off_t off;
  53.      int len;
  54. {
  55.     off_t seek_off = UVUBLK + off;
  56.     kmem_open(); /* make sure it is open */
  57.     if (lseek(KmemFd, (char *) seek_off, SEEK_SET) != seek_off) {
  58. syslog(LOG_EMERG, "lseek failed on /dev/kmem: %m");
  59. exit(1);
  60.     }
  61.     if (write(KmemFd, addr, len) != len) {
  62. syslog(LOG_EMERG, "write failed on /dev/kmem: %m");
  63. exit(1);
  64.     }
  65.     return (0);
  66. }
  67. /* UHUHUH, this crazy code is still required for 3.2v4.2 */
  68. uid_t
  69. seteuid(id)
  70.      uid_t id;
  71. {
  72.     struct user u;
  73.     return (wrub(&id, (off_t) & u.u_uid - (off_t) & u, sizeof(id)));
  74. }
  75. uid_t
  76. setruid(id)
  77.      uid_t id;
  78. {
  79.     struct user u;
  80.     return (wrub(&id, (off_t) & u.u_ruid - (off_t) & u, sizeof(id)));
  81. }
  82. uid_t
  83. setegid(id)
  84.      uid_t id;
  85. {
  86.     struct user u;
  87.     return (wrub(&id, (off_t) & u.u_gid - (off_t) & u, sizeof(id)));
  88. }
  89. uid_t
  90. setrgid(id)
  91.      uid_t id;
  92. {
  93.     struct user u;
  94.     return (wrub(&id, (off_t) & u.u_rgid - (off_t) & u, sizeof(id)));
  95. }
  96. uid_t
  97. setuid(id)
  98.      uid_t id;
  99. {
  100.     (void) seteuid(id);
  101.     (void) setruid(id);
  102.     return (0);
  103. }
  104. uid_t
  105. setgid(id)
  106.      uid_t id;
  107. {
  108.     (void) setegid(id);
  109.     (void) setrgid(id);
  110.     return (0);
  111. }
  112. uid_t
  113. setreuid(ruid, euid)
  114.      uid_t ruid, euid;
  115. {
  116.     if (ruid != 0xffff)
  117. (void) setruid(ruid);
  118.     if (euid != 0xffff)
  119. (void) seteuid(euid);
  120.     return (0);
  121. }
  122. /*
  123.  * Copyright (c) 1989, 1991 The Regents of the University of California.
  124.  * All rights reserved.
  125.  *
  126.  * Redistribution and use in source and binary forms, with or without
  127.  * modification, are permitted provided that the following conditions
  128.  * are met:
  129.  * 1. Redistributions of source code must retain the above copyright
  130.  *    notice, this list of conditions and the following disclaimer.
  131.  * 2. Redistributions in binary form must reproduce the above copyright
  132.  *    notice, this list of conditions and the following disclaimer in the
  133.  *    documentation and/or other materials provided with the distribution.
  134.  * 3. All advertising materials mentioning features or use of this software
  135.  *    must display the following acknowledgement:
  136.  *  This product includes software developed by the University of
  137.  *  California, Berkeley and its contributors.
  138.  * 4. Neither the name of the University nor the names of its contributors
  139.  *    may be used to endorse or promote products derived from this software
  140.  *    without specific prior written permission.
  141.  *
  142.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  143.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  144.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  145.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  146.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  147.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  148.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  149.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  150.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  151.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  152.  * SUCH DAMAGE.
  153.  */
  154. #if defined(SYSLOGFILE)
  155. #include <sys/types.h>
  156. #include <sys/file.h>
  157. #include <sys/signal.h>
  158. #include <sys/syslog.h>
  159. #include <sys/uio.h>
  160. #include <fcntl.h>
  161. #include <varargs.h>
  162. #include <stdio.h>
  163. #include <string.h>
  164. #include <strings.h>
  165. #ifndef CONSOLE
  166. #define CONSOLE "/dev/console"
  167. #endif
  168. static int LogFile = -1; /* fd for log */
  169. static int LogStat = 0; /* status bits, set by openlog() */
  170. static char *LogTag = "syslog"; /* string to tag the entry with */
  171. static int LogFacility = LOG_USER; /* default facility code */
  172. static int LogMask = 0xff; /* mask of priorities to be logged */
  173. syslog(va_alist)
  174.      va_dcl
  175. {
  176.     va_list args;
  177.     int pri;
  178.     char *fmt;
  179.     va_start(args);
  180.     pri = va_arg(args, int);
  181.     fmt = va_arg(args, char *);
  182.     vsyslog(pri, fmt, args);
  183.     va_end(args);
  184. }
  185. vsyslog(pri, fmt, ap)
  186.      int pri;
  187.      register char *fmt;
  188.      va_list ap;
  189. {
  190.     extern int errno;
  191.     register int cnt;
  192.     register char *p;
  193.     time_t now, time();
  194.     int pid, saved_errno;
  195.     char tbuf[2048], fmt_cpy[1024], *stdp, *ctime();
  196.     sigset_t newmask, oldmask;
  197.     saved_errno = errno;
  198. #ifndef LOG_FAC
  199. #define LOG_FAC(pri)    (((pri) & LOG_FACMASK) >> 3)
  200. #endif
  201. #ifndef LOG_PRI
  202. #define LOG_PRI(pri)    ((pri) & LOG_PRIMASK)
  203. #endif
  204.     /* see if we should just throw out this message */
  205.     if ((u_int) LOG_FAC(pri) >= (1 << LOG_NFACILITIES) ||
  206. (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) ||
  207. (pri & ~(LOG_PRIMASK | LOG_FACMASK)))
  208. return;
  209.     if (LogFile < 0)
  210. openlog(LogTag, LogStat | LOG_NDELAY, 0);
  211.     /* set default facility if none specified */
  212.     if ((pri & LOG_FACMASK) == 0)
  213. pri |= LogFacility;
  214.     /* build the message */
  215.     (void) time(&now);
  216.     (void) sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);/**/
  217. /*  (void)sprintf(tbuf, "%3o %.15s ", pri, ctime(&now) + 4); /**/
  218.     for (p = tbuf; *p; ++p);
  219. #ifndef LOG_PERROR
  220. #define LOG_PERROR 0x20
  221. #endif
  222.     if (LogStat & LOG_PERROR)
  223. stdp = p;
  224.     if (LogTag) {
  225. (void) strcpy(p, LogTag);
  226. for (; *p; ++p);
  227.     }
  228.     if (LogStat & LOG_PID) {
  229. (void) sprintf(p, "[%d]", getpid());
  230. for (; *p; ++p);
  231.     }
  232.     if (LogTag) {
  233. *p++ = ':';
  234. *p++ = ' ';
  235.     }
  236.     /* substitute error message for %m */
  237.     {
  238. register char ch, *t1, *t2;
  239. /*      char *strerror(); /* */
  240. for (t1 = fmt_cpy; ch = *fmt; ++fmt)
  241.     if (ch == '%' && fmt[1] == 'm') {
  242. ++fmt;
  243. for (t2 = strerror(saved_errno);
  244.      *t1 = *t2++; ++t1);
  245.     }
  246.     else
  247. *t1++ = ch;
  248. *t1 = '';
  249.     }
  250.     (void) vsprintf(p, fmt_cpy, ap);
  251.     cnt = strlen(tbuf);
  252.     tbuf[cnt++] = 'n';
  253.     /* output to stderr if requested */
  254.     if (LogStat & LOG_PERROR)
  255. write(2, stdp, cnt - (stdp - tbuf));
  256.     /* output the message to the local logger */
  257.     if (write(LogFile, tbuf, cnt) == cnt)
  258. return;
  259.     /* output the message to the console */
  260.     pid = vfork();
  261.     if (pid == -1)
  262. return;
  263.     if (pid == 0) {
  264. int fd;
  265. int saveerrno;
  266. sigfillset(&newmask);
  267. sigdelset(&newmask, SIGALRM);
  268. (void) sigprocmask(SIG_SETMASK, &newmask, &oldmask);
  269. (void) signal(SIGALRM, SIG_DFL);
  270. (void) alarm((u_int) 5);
  271. fd = open(CONSOLE, O_WRONLY, 0);
  272. saveerrno = errno;
  273. (void) alarm((u_int) 0);
  274. errno = saveerrno;
  275. if (fd < 0)
  276.     return;
  277. (void) strcat(tbuf, "r");
  278. p = index(tbuf, '>') + 1;
  279. (void) write(fd, p, cnt + 1 - (p - tbuf));
  280. (void) close(fd);
  281. _exit(0);
  282.     }
  283.     if (!(LogStat & LOG_NOWAIT))
  284. while ((cnt = wait((int *) 0)) > 0 && cnt != pid);
  285. }
  286. /*
  287.  * OPENLOG -- open system log
  288.  */
  289. openlog(ident, logstat, logfac)
  290.      char *ident;
  291.      int logstat, logfac;
  292. {
  293.     if (ident != NULL)
  294. LogTag = ident;
  295.     LogStat = logstat;
  296.     if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0)
  297. LogFacility = logfac;
  298.     if (LogFile == -1) {
  299. LogFile = open(SYSLOGFILE, O_WRONLY | O_APPEND | O_SYNC);
  300. /**/
  301. /*      LogFile = open(SYSLOGFILE, O_WRONLY|O_APPEND);      /**/
  302.     }
  303. }
  304. /*
  305.  * CLOSELOG -- close the system log
  306.  */
  307. closelog()
  308. {
  309.     (void) close(LogFile);
  310.     LogFile = -1;
  311. }
  312. /*
  313.  * SETLOGMASK -- set the log mask level
  314.  */
  315. setlogmask(pmask)
  316.      int pmask;
  317. {
  318.     int omask;
  319.     omask = LogMask;
  320.     if (pmask != 0)
  321. LogMask = pmask;
  322.     return (omask);
  323. }
  324. #endif /* defined(SYSLOGFILE) */
  325. /* Need own getcwd() because of the way getcwd is implemented in SCO UNIX */
  326. /*
  327.  * Copyright (c) 1989, 1991 The Regents of the University of California.
  328.  * All rights reserved.
  329.  *
  330.  * Redistribution and use in source and binary forms, with or without
  331.  * modification, are permitted provided that the following conditions
  332.  * are met:
  333.  * 1. Redistributions of source code must retain the above copyright
  334.  *    notice, this list of conditions and the following disclaimer.
  335.  * 2. Redistributions in binary form must reproduce the above copyright
  336.  *    notice, this list of conditions and the following disclaimer in the
  337.  *    documentation and/or other materials provided with the distribution.
  338.  * 3. All advertising materials mentioning features or use of this software
  339.  *    must display the following acknowledgement:
  340.  *  This product includes software developed by the University of
  341.  *  California, Berkeley and its contributors.
  342.  * 4. Neither the name of the University nor the names of its contributors
  343.  *    may be used to endorse or promote products derived from this software
  344.  *    without specific prior written permission.
  345.  *
  346.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  347.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  348.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  349.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  350.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  351.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  352.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  353.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  354.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  355.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  356.  * SUCH DAMAGE.
  357.  */
  358. #if defined(LIBC_SCCS) && !defined(lint)
  359. static char sccsid[] = "@(#)getcwd.c    5.11 (Berkeley) 2/24/91";
  360. #endif /* LIBC_SCCS and not lint */
  361. #include <sys/param.h>
  362. #ifndef HAVE_LSTAT
  363. #define lstat stat
  364. #endif
  365. #include <sys/stat.h>
  366. #include <errno.h>
  367. #include <dirent.h>
  368. #include <stdio.h>
  369. #include <string.h>
  370. #ifdef HAVE_D_NAMLEN
  371. #define DNAMLEN(dp) (dp->d_namlen)
  372. #else
  373. #define DNAMLEN(dp) (strlen(dp->d_name))
  374. #endif
  375. #define ISDOT(dp) 
  376.     (dp->d_name[0] == '.' && (dp->d_name[1] == '' || 
  377.         dp->d_name[1] == '.' && dp->d_name[2] == ''))
  378. char *
  379.      getcwd(pt, size)
  380.      char *pt;
  381.      int size;
  382. {
  383.     register struct dirent *dp;
  384.     register DIR *dir;
  385.     register dev_t dev;
  386.     register ino_t ino;
  387.     register int first;
  388.     register char *bpt, *bup;
  389.     struct stat s;
  390.     dev_t root_dev;
  391.     ino_t root_ino;
  392.     size_t ptsize, upsize;
  393.     int save_errno;
  394.     char *ept, *eup, *up, *ptr;
  395.     /*
  396.      * If no buffer specified by the user, allocate one as necessary.
  397.      * If a buffer is specified, the size has to be non-zero.  The path
  398.      * is built from the end of the buffer backwards.
  399.      */
  400.     if (pt) {
  401. ptsize = 0;
  402. if (!size) {
  403.     errno = EINVAL;
  404.     return ((char *) NULL);
  405. }
  406. ept = pt + size;
  407.     }
  408.     else {
  409. if (!(pt = (char *) malloc(ptsize = 1024 - 4)))
  410.     return ((char *) NULL);
  411. ept = pt + ptsize;
  412.     }
  413.     bpt = ept - 1;
  414.     *bpt = '';
  415.     /*
  416.      * Allocate bytes (1024 - malloc space) for the string of "../"'s.
  417.      * Should always be enough (it's 340 levels).  If it's not, allocate
  418.      * as necessary.  Special * case the first stat, it's ".", not "..".
  419.      */
  420.     if (!(up = (char *) malloc(upsize = 1024 - 4)))
  421. goto err;
  422.     eup = up + MAXPATHLEN;
  423.     bup = up;
  424.     up[0] = '.';
  425.     up[1] = '';
  426.     /* Save root values, so know when to stop. */
  427.     if (stat("/", &s))
  428. goto err;
  429.     root_dev = s.st_dev;
  430.     root_ino = s.st_ino;
  431.     errno = 0; /* XXX readdir has no error return. */
  432.     for (first = 1;; first = 0) {
  433. /* Stat the current level. */
  434. if (lstat(up, &s))
  435.     goto err;
  436. /* Save current node values. */
  437. ino = s.st_ino;
  438. dev = s.st_dev;
  439. /* Check for reaching root. */
  440. if (root_dev == dev && root_ino == ino) {
  441.     *--bpt = '/';
  442.     /*
  443.      * It's unclear that it's a requirement to copy the
  444.      * path to the beginning of the buffer, but it's always
  445.      * been that way and stuff would probably break.
  446.      */
  447.     (void) bcopy(bpt, pt, ept - bpt);
  448.     free(up);
  449.     return (pt);
  450. }
  451. /*
  452.  * Build pointer to the parent directory, allocating memory
  453.  * as necessary.  Max length is 3 for "../", the largest
  454.  * possible component name, plus a trailing NULL.
  455.  */
  456. if (bup + 3 + MAXNAMLEN + 1 >= eup) {
  457.     off_t len = bup - up;
  458.     if (!(ptr = (char *) realloc(up, upsize *= 2)))
  459. goto err;
  460.     up = ptr;
  461.     bup = up + len;
  462.     eup = up + upsize;
  463. }
  464. *bup++ = '.';
  465. *bup++ = '.';
  466. *bup = '';
  467. /* Open and stat parent directory. */
  468. if (!(dir = opendir(up)) || fstat(dir->dd_fd, &s))
  469.     goto err;
  470. /* Add trailing slash for next directory. */
  471. *bup++ = '/';
  472. /*
  473.  * If it's a mount point, have to stat each element because
  474.  * the inode number in the directory is for the entry in the
  475.  * parent directory, not the inode number of the mounted file.
  476.  */
  477. save_errno = 0;
  478. if (s.st_dev == dev) {
  479.     for (;;) {
  480. if (!(dp = readdir(dir)))
  481.     goto notfound;
  482. if (dp->d_fileno == ino)
  483.     break;
  484.     }
  485. }
  486. else
  487.     for (;;) {
  488. if (!(dp = readdir(dir)))
  489.     goto notfound;
  490. if (ISDOT(dp))
  491.     continue;
  492. bcopy(dp->d_name, bup, DNAMLEN(dp) + 1);
  493. /* Save the first error for later. */
  494. if (lstat(up, &s)) {
  495.     if (!save_errno)
  496. save_errno = errno;
  497.     errno = 0;
  498.     continue;
  499. }
  500. if (s.st_dev == dev && s.st_ino == ino)
  501.     break;
  502.     }
  503. /*
  504.  * Check for length of the current name, preceding slash,
  505.  * leading slash.
  506.  */
  507. if (bpt - pt <= DNAMLEN(dp) + (first ? 1 : 2)) {
  508.     size_t len, off;
  509.     if (!ptsize) {
  510. errno = ERANGE;
  511. goto err;
  512.     }
  513.     off = bpt - pt;
  514.     len = ept - bpt;
  515.     if (!(ptr = (char *) realloc(pt, ptsize *= 2)))
  516. goto err;
  517.     pt = ptr;
  518.     bpt = pt + off;
  519.     ept = pt + ptsize;
  520.     (void) bcopy(bpt, ept - len, len);
  521.     bpt = ept - len;
  522. }
  523. if (!first)
  524.     *--bpt = '/';
  525. bpt -= DNAMLEN(dp);
  526. bcopy(dp->d_name, bpt, DNAMLEN(dp));
  527. (void) closedir(dir);
  528. /* Truncate any file name. */
  529. *bup = '';
  530.     }
  531.   notfound:
  532.     /*
  533.      * If readdir set errno, use it, not any saved error; otherwise,
  534.      * didn't find the current directory in its parent directory, set
  535.      * errno to ENOENT.
  536.      */
  537.     if (!errno)
  538. errno = save_errno ? save_errno : ENOENT;
  539.     /* FALLTHROUGH */
  540.   err:
  541.     if (ptsize && !pt)
  542. free(pt);
  543.     if (!up)
  544. free(up);
  545.     return ((char *) NULL);
  546. }
  547. char *
  548.      getwd(b)
  549.      char *b;
  550. {
  551.     char *p;
  552.     uid_t euid = geteuid();
  553.     seteuid(0);
  554.     getcwd(b, MAXPATHLEN);
  555.     p = getcwd(b, MAXPATHLEN);
  556.     seteuid(euid);
  557.     return (p);
  558. }
  559. /*
  560.  * Copyright (c) 1983 Regents of the University of California.
  561.  * All rights reserved.
  562.  *
  563.  * Redistribution and use in source and binary forms, with or without
  564.  * modification, are permitted provided that the following conditions
  565.  * are met:
  566.  * 1. Redistributions of source code must retain the above copyright
  567.  *    notice, this list of conditions and the following disclaimer.
  568.  * 2. Redistributions in binary form must reproduce the above copyright
  569.  *    notice, this list of conditions and the following disclaimer in the
  570.  *    documentation and/or other materials provided with the distribution.
  571.  * 3. All advertising materials mentioning features or use of this software
  572.  *    must display the following acknowledgement:
  573.  *  This product includes software developed by the University of
  574.  *  California, Berkeley and its contributors.
  575.  * 4. Neither the name of the University nor the names of its contributors
  576.  *    may be used to endorse or promote products derived from this software
  577.  *    without specific prior written permission.
  578.  *
  579.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  580.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  581.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  582.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  583.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  584.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  585.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  586.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  587.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  588.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  589.  * SUCH DAMAGE.
  590.  */
  591. #if !defined(lint)
  592. static char sccsid[] = "@(#)initgroups.c    5.6 (Berkeley) 6/1/90";
  593. static char rcsid[] = "@(#)$Id: sco.c,v 1.6 1999/08/27 14:18:42 wuftpd Exp $";
  594. #endif /* !lint */
  595. #include <stdio.h>
  596. #include <grp.h>
  597. #ifndef NGROUPS
  598. #ifdef NGROUPS_MAX
  599. #define NGROUPS  NGROUPS_MAX
  600. #else /* !NGROUPS_MAX */
  601. #define NGROUPS  8
  602. #endif /* NGROUPS_MAX */
  603. #endif /* !NGROUPS */
  604. struct group *getgrent();
  605. initgroups(uname, agroup)
  606.      char *uname;
  607.      int agroup;
  608. {
  609.     int groups[NGROUPS], ngroups = 0;
  610.     register struct group *grp;
  611.     register int i;
  612.     /*
  613.      * If installing primary group, duplicate it;
  614.      * the first element of groups is the effective gid
  615.      * and will be overwritten when a setgid file is executed.
  616.      */
  617.     if (agroup >= 0) {
  618. groups[ngroups++] = agroup;
  619. groups[ngroups++] = agroup;
  620.     }
  621.     setgrent();
  622.     while (grp = getgrent()) {
  623. if (grp->gr_gid == agroup)
  624.     continue;
  625. for (i = 0; grp->gr_mem[i]; i++)
  626.     if (!strcmp(grp->gr_mem[i], uname)) {
  627. if (ngroups == NGROUPS) {
  628.     fprintf(stderr, "initgroups: %s is in too many groupsn", uname);
  629.     goto toomany;
  630. }
  631. groups[ngroups++] = grp->gr_gid;
  632.     }
  633.     }
  634.   toomany:
  635.     endgrent();
  636.     if (setgroups(ngroups, groups) < 0) {
  637. perror("setgroups");
  638. return (-1);
  639.     }
  640.     return (0);
  641. }
  642. #else
  643. /* this will keep the preprocessor quiet */
  644. int SCOdummy()
  645. {
  646.     return (0);
  647. }
  648. #endif /* _SCO_DS */