pwd.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * <pwd.h> wrapper functions.
  3. *
  4. * Authors:
  5. * Jonathan Pryor ([email protected])
  6. *
  7. * Copyright (C) 2004-2005 Jonathan Pryor
  8. */
  9. #include <pwd.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include "map.h"
  15. #include "mph.h"
  16. G_BEGIN_DECLS
  17. static const mph_string_offset_t
  18. passwd_offsets[] = {
  19. MPH_STRING_OFFSET (struct passwd, pw_name, MPH_STRING_OFFSET_PTR),
  20. MPH_STRING_OFFSET (struct passwd, pw_passwd, MPH_STRING_OFFSET_PTR),
  21. MPH_STRING_OFFSET (struct passwd, pw_gecos, MPH_STRING_OFFSET_PTR),
  22. MPH_STRING_OFFSET (struct passwd, pw_dir, MPH_STRING_OFFSET_PTR),
  23. MPH_STRING_OFFSET (struct passwd, pw_shell, MPH_STRING_OFFSET_PTR)
  24. };
  25. static const mph_string_offset_t
  26. mph_passwd_offsets[] = {
  27. MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_name, MPH_STRING_OFFSET_PTR),
  28. MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_passwd, MPH_STRING_OFFSET_PTR),
  29. MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_gecos, MPH_STRING_OFFSET_PTR),
  30. MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_dir, MPH_STRING_OFFSET_PTR),
  31. MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Passwd, pw_shell, MPH_STRING_OFFSET_PTR)
  32. };
  33. /*
  34. * Copy the native `passwd' structure to it's managed representation.
  35. *
  36. * To minimize separate mallocs, all the strings are allocated within the same
  37. * memory block (stored in _pw_buf_).
  38. */
  39. static int
  40. copy_passwd (struct Mono_Posix_Syscall__Passwd *to, struct passwd *from)
  41. {
  42. char *buf;
  43. buf = _mph_copy_structure_strings (to, mph_passwd_offsets,
  44. from, passwd_offsets, sizeof(passwd_offsets)/sizeof(passwd_offsets[0]));
  45. to->pw_uid = from->pw_uid;
  46. to->pw_gid = from->pw_gid;
  47. to->_pw_buf_ = buf;
  48. if (buf == NULL) {
  49. return -1;
  50. }
  51. return 0;
  52. }
  53. gint32
  54. Mono_Posix_Syscall_getpwnam (const char *name, struct Mono_Posix_Syscall__Passwd *pwbuf)
  55. {
  56. struct passwd *pw;
  57. if (pwbuf == NULL) {
  58. errno = EFAULT;
  59. return -1;
  60. }
  61. errno = 0;
  62. pw = getpwnam (name);
  63. if (pw == NULL)
  64. return -1;
  65. if (copy_passwd (pwbuf, pw) == -1) {
  66. errno = ENOMEM;
  67. return -1;
  68. }
  69. return 0;
  70. }
  71. gint32
  72. Mono_Posix_Syscall_getpwuid (mph_uid_t uid, struct Mono_Posix_Syscall__Passwd *pwbuf)
  73. {
  74. struct passwd *pw;
  75. if (pwbuf == NULL) {
  76. errno = EFAULT;
  77. return -1;
  78. }
  79. errno = 0;
  80. pw = getpwuid (uid);
  81. if (pw == NULL) {
  82. return -1;
  83. }
  84. if (copy_passwd (pwbuf, pw) == -1) {
  85. errno = ENOMEM;
  86. return -1;
  87. }
  88. return 0;
  89. }
  90. #ifdef HAVE_GETPWNAM_R
  91. gint32
  92. Mono_Posix_Syscall_getpwnam_r (const char *name,
  93. struct Mono_Posix_Syscall__Passwd *pwbuf,
  94. void **pwbufp)
  95. {
  96. char *buf, *buf2;
  97. size_t buflen;
  98. int r;
  99. struct passwd _pwbuf;
  100. if (pwbuf == NULL) {
  101. errno = EFAULT;
  102. return -1;
  103. }
  104. buf = buf2 = NULL;
  105. buflen = 2;
  106. do {
  107. buf2 = realloc (buf, buflen *= 2);
  108. if (buf2 == NULL) {
  109. free (buf);
  110. errno = ENOMEM;
  111. return -1;
  112. }
  113. buf = buf2;
  114. errno = 0;
  115. } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
  116. recheck_range (r));
  117. if (r == 0 && !(*pwbufp))
  118. /* On solaris, this function returns 0 even if the entry was not found */
  119. r = errno = ENOENT;
  120. if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
  121. r = errno = ENOMEM;
  122. free (buf);
  123. return r;
  124. }
  125. #endif /* ndef HAVE_GETPWNAM_R */
  126. #ifdef HAVE_GETPWUID_R
  127. gint32
  128. Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
  129. struct Mono_Posix_Syscall__Passwd *pwbuf,
  130. void **pwbufp)
  131. {
  132. char *buf, *buf2;
  133. size_t buflen;
  134. int r;
  135. struct passwd _pwbuf;
  136. if (pwbuf == NULL) {
  137. errno = EFAULT;
  138. return -1;
  139. }
  140. buf = buf2 = NULL;
  141. buflen = 2;
  142. do {
  143. buf2 = realloc (buf, buflen *= 2);
  144. if (buf2 == NULL) {
  145. free (buf);
  146. errno = ENOMEM;
  147. return -1;
  148. }
  149. buf = buf2;
  150. errno = 0;
  151. } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
  152. recheck_range (r));
  153. if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
  154. r = errno = ENOMEM;
  155. free (buf);
  156. return r;
  157. }
  158. #endif /* ndef HAVE_GETPWUID_R */
  159. gint32
  160. Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
  161. {
  162. struct passwd *pw;
  163. if (pwbuf == NULL) {
  164. errno = EFAULT;
  165. return -1;
  166. }
  167. errno = 0;
  168. pw = getpwent ();
  169. if (pw == NULL)
  170. return -1;
  171. if (copy_passwd (pwbuf, pw) == -1) {
  172. errno = ENOMEM;
  173. return -1;
  174. }
  175. return 0;
  176. }
  177. #ifdef HAVE_FGETPWENT
  178. gint32
  179. Mono_Posix_Syscall_fgetpwent (void *stream, struct Mono_Posix_Syscall__Passwd *pwbuf)
  180. {
  181. struct passwd *pw;
  182. if (pwbuf == NULL) {
  183. errno = EFAULT;
  184. return -1;
  185. }
  186. errno = 0;
  187. pw = fgetpwent ((FILE*) stream);
  188. if (pw == NULL)
  189. return -1;
  190. if (copy_passwd (pwbuf, pw) == -1) {
  191. errno = ENOMEM;
  192. return -1;
  193. }
  194. return 0;
  195. }
  196. #endif /* ndef HAVE_FGETPWENT */
  197. int
  198. Mono_Posix_Syscall_setpwent (void)
  199. {
  200. errno = 0;
  201. do {
  202. setpwent ();
  203. } while (errno == EINTR);
  204. mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE);
  205. return 0;
  206. }
  207. int
  208. Mono_Posix_Syscall_endpwent (void)
  209. {
  210. errno = 0;
  211. endpwent ();
  212. if (errno == EIO)
  213. return -1;
  214. return 0;
  215. }
  216. G_END_DECLS
  217. /*
  218. * vim: noexpandtab
  219. */