getpw_r.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include "pwf.h"
  2. #include <pthread.h>
  3. #define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
  4. static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
  5. {
  6. FILE *f;
  7. char *line = 0;
  8. size_t len = 0;
  9. int rv = 0;
  10. int cs;
  11. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  12. f = fopen("/etc/passwd", "rb");
  13. if (!f) {
  14. rv = errno;
  15. goto done;
  16. }
  17. *res = 0;
  18. while (__getpwent_a(f, pw, &line, &len)) {
  19. if (name && !strcmp(name, pw->pw_name)
  20. || !name && pw->pw_uid == uid) {
  21. if (size < len) {
  22. rv = ERANGE;
  23. break;
  24. }
  25. *res = pw;
  26. memcpy(buf, line, len);
  27. FIX(name);
  28. FIX(passwd);
  29. FIX(gecos);
  30. FIX(dir);
  31. FIX(shell);
  32. break;
  33. }
  34. }
  35. free(line);
  36. fclose(f);
  37. done:
  38. pthread_setcancelstate(cs, 0);
  39. return rv;
  40. }
  41. int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
  42. {
  43. return getpw_r(name, 0, pw, buf, size, res);
  44. }
  45. int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
  46. {
  47. return getpw_r(0, uid, pw, buf, size, res);
  48. }