⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getpwent.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  POSIX 1003.1b - 9.2.2 - User Database Access Routines * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: getpwent.c,v 1.9.2.1 2003/09/04 18:46:58 joel Exp $ */#if HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <sys/types.h>#include <pwd.h>#include <grp.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <ctype.h>#include <rtems/libio_.h>/* * Static, thread-unsafe, buffers */static FILE *passwd_fp;static char pwbuf[200];static struct passwd pwent;static FILE *group_fp;static char grbuf[200];static struct group grent;/* * Initialize useable but dummy databases */void init_etc_passwd_group(void){  FILE *fp;  static char etc_passwd_initted = 0;  if (etc_passwd_initted)    return;  etc_passwd_initted = 1;  mkdir("/etc", 0777);  /*   *  Initialize /etc/passwd   */  if ((fp = fopen("/etc/passwd", "r")) != NULL) {    fclose(fp);  }  else if ((fp = fopen("/etc/passwd", "w")) != NULL) {    fprintf(fp, "root:*:0:0:root::/:/bin/sh\n"                 "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"                 "tty:!:2:2:tty owner::/:/bin/false\n" );    fclose(fp);  }  /*   *  Initialize /etc/group   */  if ((fp = fopen("/etc/group", "r")) != NULL) {    fclose(fp);  }  else if ((fp = fopen("/etc/group", "w")) != NULL) {    fprintf( fp, "root:x:0:root\n"                 "rtems:x:1:rtems\n"                 "tty:x:2:tty\n" );    fclose(fp);  }}/* * Extract a string value from the database */static intscanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag){  int c;  *name = *bufp;  for (;;) {    c = getc(fp);    if (c == ':') {        if (nlFlag)            return 0;        break;    }    if (c == '\n') {        if (!nlFlag)            return 0;        break;    }    if (c == EOF)      return 0;    if (*nleft < 2)      return 0;    **bufp = c;    ++(*bufp);    --(*nleft);  }  **bufp = '\0';  ++(*bufp);  --(*nleft);  return 1;}/* * Extract an integer value from the database */static intscanInt(FILE *fp, int *val){  int c;  unsigned int i = 0;  unsigned int limit = INT_MAX;  int sign = 0;  int d;  for (;;) {    c = getc(fp);    if (c == ':')      break;    if (sign == 0) {      if (c == '-') {        sign = -1;        limit++;        continue;      }      sign = 1;    }    if (!isdigit(c))      return 0;    d = c - '0';    if ((i > (limit / 10))     || ((i == (limit / 10)) && (d > (limit % 10))))      return 0;    i = i * 10 + d;  }  if (sign == 0)    return 0;  *val = i * sign;  return 1;}/* * Extract a single password record from the database */static int scanpw(  FILE *fp,  struct passwd *pwd,  char *buffer,  size_t bufsize){  int pwuid, pwgid;  if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0)   || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0)   || !scanInt(fp, &pwuid)   || !scanInt(fp, &pwgid)   || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0)   || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0)   || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0)   || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1))    return 0;  pwd->pw_uid = pwuid;  pwd->pw_gid = pwgid;  return 1;}static int getpw_r(  const char     *name,  int             uid,  struct passwd  *pwd,  char           *buffer,  size_t          bufsize,  struct passwd **result){  FILE *fp;  int match;  init_etc_passwd_group();  if ((fp = fopen("/etc/passwd", "r")) == NULL) {    errno = EINVAL;    return -1;  }  for(;;) {    if (!scanpw(fp, pwd, buffer, bufsize)) {      errno = EINVAL;      fclose(fp);      return -1;    }    if (name) {      match = (strcmp(pwd->pw_name, name) == 0);    }    else {      match = (pwd->pw_uid == uid);    }    if (match) {      fclose(fp);      *result = pwd;      return 0;    }  }  fclose(fp);  errno = EINVAL;  return -1;}int getpwnam_r(  const char     *name,  struct passwd  *pwd,  char           *buffer,  size_t          bufsize,  struct passwd **result){  return getpw_r(name, 0, pwd, buffer, bufsize, result);}struct passwd *getpwnam(   const char *name){  struct passwd *p;  if(getpwnam_r(name, &pwent, pwbuf, sizeof pwbuf, &p))    return NULL;  return p;}int getpwuid_r(  uid_t           uid,  struct passwd  *pwd,  char           *buffer,  size_t          bufsize,  struct passwd **result){  return getpw_r(NULL, uid, pwd, buffer, bufsize, result);}struct passwd *getpwuid(  uid_t uid){  struct passwd *p;  if(getpwuid_r(uid, &pwent, pwbuf, sizeof pwbuf, &p))    return NULL;  return p;}struct passwd *getpwent(){  if (passwd_fp == NULL)    return NULL;  if (!scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf))    return NULL;  return &pwent;}void setpwent(void){  init_etc_passwd_group();  if (passwd_fp != NULL)    fclose(passwd_fp);  passwd_fp = fopen("/etc/passwd", "r");}void endpwent(void){  if (passwd_fp != NULL)    fclose(passwd_fp);}/* * Extract a single group record from the database */static int scangr(  FILE *fp,  struct group *grp,  char *buffer,  size_t bufsize){  int grgid;  char *grmem, *cp;  int memcount;  if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0)   || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0)   || !scanInt(fp, &grgid)   || !scanString(fp, &grmem, &buffer, &bufsize, 1))    return 0;  grp->gr_gid = grgid;  /*   * Determine number of members   */  for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {    if(*cp == ',')      memcount++;  }  /*   * Hack to produce (hopefully) a suitably-aligned array of pointers   */  if (bufsize < (((memcount+1)*sizeof(char *)) + 15))    return 0;  grp->gr_mem = (char **)(((unsigned long)buffer + 15) & ~15);  /*   * Fill in pointer array   */  grp->gr_mem[0] = grmem;  for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) {    if(*cp == ',') {      *cp = '\0';      grp->gr_mem[memcount++] = cp + 1;    }  }  grp->gr_mem[memcount] = NULL;  return 1;}static int getgr_r(  const char     *name,  int             gid,  struct group   *grp,  char           *buffer,  size_t          bufsize,  struct group  **result){  FILE *fp;  int match;  init_etc_passwd_group();  if ((fp = fopen("/etc/group", "r")) == NULL) {    errno = EINVAL;    return -1;  }  for(;;) {    if (!scangr(fp, grp, buffer, bufsize)) {      errno = EINVAL;      fclose(fp);      return -1;    }    if (name) {      match = (strcmp(grp->gr_name, name) == 0);    }    else {      match = (grp->gr_gid == gid);    }    if (match) {      fclose(fp);      *result = grp;      return 0;    }  }  fclose(fp);  errno = EINVAL;  return -1;}int getgrnam_r(  const char     *name,  struct group   *grp,  char           *buffer,  size_t          bufsize,  struct group  **result){  return getgr_r(name, 0, grp, buffer, bufsize, result);}struct group *getgrnam(   const char *name){  struct group *p;  if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))    return NULL;  return p;}int getgrgid_r(  gid_t           gid,  struct group   *grp,  char           *buffer,  size_t          bufsize,  struct group  **result){  return getgr_r(NULL, gid, grp, buffer, bufsize, result);}struct group *getgrgid(  gid_t gid){  struct group *p;  if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))    return NULL;  return p;}struct group *getgrent(){  if (group_fp == NULL)    return NULL;  if (!scangr(group_fp, &grent, grbuf, sizeof grbuf))    return NULL;  return &grent;}void setgrent(void){  init_etc_passwd_group();  if (group_fp != NULL)    fclose(group_fp);  group_fp = fopen("/etc/group", "r");}void endgrent(void){  if (group_fp != NULL)    fclose(group_fp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -