scpmisc.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* Dropbear Note: This file is based on OpenSSH 4.3p2. Avoid unnecessary
  2. changes to simplify future updates */
  3. /*
  4. * Copyright (c) 2000 Markus Friedl. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /*RCSID("OpenBSD: misc.c,v 1.22 2003/09/18 08:49:45 markus Exp ");*/
  27. /* For xmalloc, xfree etc:
  28. * Author: Tatu Ylonen <ylo@cs.hut.fi>
  29. * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  30. * All rights reserved
  31. * Versions of malloc and friends that check their results, and never return
  32. * failure (they call fatal if they encounter an error).
  33. *
  34. * As far as I am concerned, the code I have written for this software
  35. * can be used freely for any purpose. Any derived versions of this
  36. * software must be clearly marked as such, and if the derived work is
  37. * incompatible with the protocol description in the RFC file, it must be
  38. * called by a name other than "ssh" or "Secure Shell".
  39. */
  40. /*RCSID("OpenBSD: xmalloc.c,v 1.16 2001/07/23 18:21:46 stevesk Exp ");*/
  41. #define _GNU_SOURCE
  42. #include "includes.h"
  43. #include "scpmisc.h"
  44. void *
  45. xmalloc(size_t size)
  46. {
  47. void *ptr;
  48. if (size == 0) {
  49. fprintf(stderr, "xmalloc: zero size\n");
  50. exit(EXIT_FAILURE);
  51. }
  52. ptr = malloc(size);
  53. if (ptr == NULL) {
  54. fprintf(stderr, "xmalloc: out of memory (allocating %lu bytes)\n", (u_long) size);
  55. exit(EXIT_FAILURE);
  56. }
  57. return ptr;
  58. }
  59. void *
  60. xrealloc(void *ptr, size_t new_size)
  61. {
  62. void *new_ptr;
  63. if (new_size == 0) {
  64. fprintf(stderr, "xrealloc: zero size\n");
  65. exit(EXIT_FAILURE);
  66. }
  67. if (ptr == NULL)
  68. new_ptr = malloc(new_size);
  69. else
  70. new_ptr = realloc(ptr, new_size);
  71. if (new_ptr == NULL) {
  72. fprintf(stderr, "xrealloc: out of memory (new_size %lu bytes)\n", (u_long) new_size);
  73. exit(EXIT_FAILURE);
  74. }
  75. return new_ptr;
  76. }
  77. void
  78. xfree(void *ptr)
  79. {
  80. if (ptr == NULL) {
  81. fprintf(stderr, "xfree: NULL pointer given as argument\n");
  82. exit(EXIT_FAILURE);
  83. }
  84. free(ptr);
  85. }
  86. char *
  87. xstrdup(const char *str)
  88. {
  89. size_t len;
  90. char *cp;
  91. len = strlen(str) + 1;
  92. cp = xmalloc(len);
  93. strncpy(cp, str, len);
  94. return cp;
  95. }
  96. char *
  97. cleanhostname(char *host)
  98. {
  99. if (*host == '[' && host[strlen(host) - 1] == ']') {
  100. host[strlen(host) - 1] = '\0';
  101. return (host + 1);
  102. } else
  103. return host;
  104. }
  105. char *
  106. colon(char *cp)
  107. {
  108. int flag = 0;
  109. if (*cp == ':') /* Leading colon is part of file name. */
  110. return (0);
  111. if (*cp == '[')
  112. flag = 1;
  113. for (; *cp; ++cp) {
  114. if (*cp == '@' && *(cp+1) == '[')
  115. flag = 1;
  116. if (*cp == ']' && *(cp+1) == ':' && flag)
  117. return (cp+1);
  118. if (*cp == ':' && !flag)
  119. return (cp);
  120. if (*cp == '/')
  121. return (0);
  122. }
  123. return (0);
  124. }
  125. /* function to assist building execv() arguments */
  126. void
  127. addargs(arglist *args, char *fmt, ...)
  128. {
  129. va_list ap;
  130. char *cp;
  131. u_int nalloc;
  132. int r;
  133. va_start(ap, fmt);
  134. r = vasprintf(&cp, fmt, ap);
  135. va_end(ap);
  136. if (r == -1)
  137. fatal("addargs: argument too long");
  138. nalloc = args->nalloc;
  139. if (args->list == NULL) {
  140. nalloc = 32;
  141. args->num = 0;
  142. } else if (args->num+2 >= nalloc)
  143. nalloc *= 2;
  144. args->list = xrealloc(args->list, nalloc * sizeof(char *));
  145. args->nalloc = nalloc;
  146. args->list[args->num++] = cp;
  147. args->list[args->num] = NULL;
  148. }
  149. void
  150. replacearg(arglist *args, u_int which, char *fmt, ...)
  151. {
  152. va_list ap;
  153. char *cp;
  154. int r;
  155. va_start(ap, fmt);
  156. r = vasprintf(&cp, fmt, ap);
  157. va_end(ap);
  158. if (r == -1)
  159. fatal("replacearg: argument too long");
  160. if (which >= args->num)
  161. fatal("replacearg: tried to replace invalid arg %d >= %d",
  162. which, args->num);
  163. xfree(args->list[which]);
  164. args->list[which] = cp;
  165. }
  166. void
  167. freeargs(arglist *args)
  168. {
  169. u_int i;
  170. if (args->list != NULL) {
  171. for (i = 0; i < args->num; i++)
  172. xfree(args->list[i]);
  173. xfree(args->list);
  174. args->nalloc = args->num = 0;
  175. args->list = NULL;
  176. }
  177. }
  178. /*
  179. * NB. duplicate __progname in case it is an alias for argv[0]
  180. * Otherwise it may get clobbered by setproctitle()
  181. */
  182. char *ssh_get_progname(char *argv0)
  183. {
  184. char *p;
  185. if (argv0 == NULL)
  186. return ("unknown"); /* XXX */
  187. p = strrchr(argv0, '/');
  188. if (p == NULL)
  189. p = argv0;
  190. else
  191. p++;
  192. return (xstrdup(p));
  193. }
  194. void fatal(char* fmt,...)
  195. {
  196. va_list args;
  197. va_start(args, fmt);
  198. vfprintf(stderr, fmt, args);
  199. va_end(args);
  200. fputc('\n', stderr);
  201. exit(255);
  202. }
  203. void
  204. sanitise_stdfd(void)
  205. {
  206. int nullfd, dupfd;
  207. if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
  208. fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));
  209. exit(1);
  210. }
  211. while (++dupfd <= 2) {
  212. /* Only clobber closed fds */
  213. if (fcntl(dupfd, F_GETFL, 0) >= 0)
  214. continue;
  215. if (dup2(nullfd, dupfd) == -1) {
  216. fprintf(stderr, "dup2: %s", strerror(errno));
  217. exit(1);
  218. }
  219. }
  220. if (nullfd > 2)
  221. close(nullfd);
  222. }