1/* buildcmd.c -- build command lines from a list of arguments. 2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16*/ 17 18#include <config.h> 19 20# ifndef PARAMS 21# if defined PROTOTYPES || (defined __STDC__ && __STDC__) 22# define PARAMS(Args) Args 23# else 24# define PARAMS(Args) () 25# endif 26# endif 27 28#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) 29#include <string.h> 30#endif 31 32 33#if DO_MULTIBYTE 34# if HAVE_MBRLEN 35# include <wchar.h> 36# else 37 /* Simulate mbrlen with mblen as best we can. */ 38# define mbstate_t int 39# define mbrlen(s, n, ps) mblen (s, n) 40# endif 41#endif 42 43#ifdef HAVE_LOCALE_H 44#include <locale.h> 45#endif 46#if ENABLE_NLS 47# include <libintl.h> 48# define _(Text) gettext (Text) 49#else 50# define _(Text) Text 51#define textdomain(Domain) 52#define bindtextdomain(Package, Directory) 53#endif 54#ifdef gettext_noop 55# define N_(String) gettext_noop (String) 56#else 57/* See locate.c for explanation as to why not use (String) */ 58# define N_(String) String 59#endif 60 61#ifndef _POSIX_SOURCE 62#include <sys/param.h> 63#endif 64 65#ifdef HAVE_LIMITS_H 66#include <limits.h> 67#endif 68 69/* The presence of unistd.h is assumed by gnulib these days, so we 70 * might as well assume it too. 71 */ 72/* for sysconf() */ 73#include <unistd.h> 74 75#include <assert.h> 76 77/* COMPAT: SYSV version defaults size (and has a max value of) to 470. 78 We try to make it as large as possible. */ 79#if !defined(ARG_MAX) && defined(_SC_ARG_MAX) 80#define ARG_MAX sysconf (_SC_ARG_MAX) 81#endif 82#ifndef ARG_MAX 83#define ARG_MAX NCARGS 84#endif 85 86 87 88#include <xalloc.h> 89#include <error.h> 90 91#include "buildcmd.h" 92 93 94extern char **environ; 95 96 97static char *mbstrstr PARAMS ((const char *haystack, const char *needle)); 98 99/* Replace all instances of `replace_pat' in ARG with `linebuf', 100 and add the resulting string to the list of arguments for the command 101 to execute. 102 ARGLEN is the length of ARG, not including the null. 103 LBLEN is the length of LINEBUF, not including the null. 104 PFXLEN is the length of PREFIX. Substitution is not performed on 105 the prefix. The prefix is used if the argument contains replace_pat. 106 107 COMPAT: insertions on the SYSV version are limited to 255 chars per line, 108 and a max of 5 occurrences of replace_pat in the initial-arguments. 109 Those restrictions do not exist here. */ 110 111void 112bc_do_insert (const struct buildcmd_control *ctl, 113 struct buildcmd_state *state, 114 char *arg, size_t arglen, 115 const char *prefix, size_t pfxlen, 116 const char *linebuf, size_t lblen, 117 int initial_args) 118{ 119 /* Temporary copy of each arg with the replace pattern replaced by the 120 real arg. */ 121 static char *insertbuf; 122 char *p; 123 size_t bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */ 124 int need_prefix; 125 126 /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max 127 * may have been set to LONG_MAX (see bc_get_arg_max()). Hence 128 * this xmalloc call may be a bad idea, especially since we are 129 * adding 1 to it... 130 */ 131 if (!insertbuf) 132 insertbuf = (char *) xmalloc (ctl->arg_max + 1); 133 p = insertbuf; 134 135 do 136 { 137 size_t len; /* Length in ARG before `replace_pat'. */ 138 char *s = mbstrstr (arg, ctl->replace_pat); 139 if (s) 140 { 141 len = s - arg; 142 } 143 else 144 { 145 len = arglen; 146 } 147 148 if (bytes_left <= len) 149 break; 150 else 151 bytes_left -= len; 152 153 strncpy (p, arg, len); 154 p += len; 155 arg += len; 156 arglen -= len; 157 158 if (s) 159 { 160 if (bytes_left <= (lblen + pfxlen)) 161 break; 162 else 163 bytes_left -= (lblen + pfxlen); 164 165 if (prefix) 166 { 167 strcpy (p, prefix); 168 p += pfxlen; 169 } 170 strcpy (p, linebuf); 171 p += lblen; 172 173 arg += ctl->rplen; 174 arglen -= ctl->rplen; 175 } 176 } 177 while (*arg); 178 if (*arg) 179 error (1, 0, _("command too long")); 180 *p++ = '\0'; 181 182 bc_push_arg (ctl, state, 183 insertbuf, p - insertbuf, 184 NULL, 0, 185 initial_args); 186} 187 188static 189void do_exec(const struct buildcmd_control *ctl, 190 struct buildcmd_state *state) 191{ 192 (ctl->exec_callback)(ctl, state); 193} 194 195 196/* Return nonzero if there would not be enough room for an additional 197 * argument. We check the total number of arguments only, not the space 198 * occupied by those arguments. 199 * 200 * If we return zero, there still may not be enough room for the next 201 * argument, depending on its length. 202 */ 203static int 204bc_argc_limit_reached(int initial_args, 205 const struct buildcmd_control *ctl, 206 struct buildcmd_state *state) 207{ 208 /* Check to see if we about to exceed a limit set by xargs' -n option */ 209 if (!initial_args && ctl->args_per_exec && 210 ( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec)) 211 return 1; 212 213 /* We deliberately use an equality test here rather than >= in order 214 * to force a software failure if the code is modified in such a way 215 * that it fails to call this function for every new argument. 216 */ 217 return state->cmd_argc == ctl->max_arg_count; 218} 219 220 221/* Add ARG to the end of the list of arguments `cmd_argv' to pass 222 to the command. 223 LEN is the length of ARG, including the terminating null. 224 If this brings the list up to its maximum size, execute the command. */ 225 226void 227bc_push_arg (const struct buildcmd_control *ctl, 228 struct buildcmd_state *state, 229 const char *arg, size_t len, 230 const char *prefix, size_t pfxlen, 231 int initial_args) 232{ 233 if (!initial_args) 234 state->todo = 1; 235 236 if (arg) 237 { 238 if (state->cmd_argv_chars + len > ctl->arg_max) 239 { 240 if (initial_args || state->cmd_argc == ctl->initial_argc) 241 error (1, 0, _("can not fit single argument within argument list size limit")); 242 /* option -i (replace_pat) implies -x (exit_if_size_exceeded) */ 243 if (ctl->replace_pat 244 || (ctl->exit_if_size_exceeded && 245 (ctl->lines_per_exec || ctl->args_per_exec))) 246 error (1, 0, _("argument list too long")); 247 do_exec (ctl, state); 248 } 249 250 if (bc_argc_limit_reached(initial_args, ctl, state)) 251 do_exec (ctl, state); 252 } 253 254 if (state->cmd_argc >= state->cmd_argv_alloc) 255 { 256 if (!state->cmd_argv) 257 { 258 state->cmd_argv_alloc = 64; 259 state->cmd_argv = (char **) xmalloc (sizeof (char *) * state->cmd_argv_alloc); 260 } 261 else 262 { 263 state->cmd_argv_alloc *= 2; 264 state->cmd_argv = (char **) xrealloc (state->cmd_argv, 265 sizeof (char *) * state->cmd_argv_alloc); 266 } 267 } 268 269 if (!arg) 270 state->cmd_argv[state->cmd_argc++] = NULL; 271 else 272 { 273 state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars; 274 if (prefix) 275 { 276 strcpy (state->argbuf + state->cmd_argv_chars, prefix); 277 state->cmd_argv_chars += pfxlen; 278 } 279 280 strcpy (state->argbuf + state->cmd_argv_chars, arg); 281 state->cmd_argv_chars += len; 282 283 /* If we have now collected enough arguments, 284 * do the exec immediately. This must be 285 * conditional on arg!=NULL, since do_exec() 286 * actually calls bc_push_arg(ctl, state, NULL, 0, false). 287 */ 288 if (bc_argc_limit_reached(initial_args, ctl, state)) 289 do_exec (ctl, state); 290 } 291 292 /* If this is an initial argument, set the high-water mark. */ 293 if (initial_args) 294 { 295 state->cmd_initial_argv_chars = state->cmd_argv_chars; 296 } 297} 298 299 300/* Finds the first occurrence of the substring NEEDLE in the string 301 HAYSTACK. Both strings can be multibyte strings. */ 302 303static char * 304mbstrstr (const char *haystack, const char *needle) 305{ 306#if DO_MULTIBYTE 307 if (MB_CUR_MAX > 1) 308 { 309 size_t hlen = strlen (haystack); 310 size_t nlen = strlen (needle); 311 mbstate_t mbstate; 312 size_t step; 313 314 memset (&mbstate, 0, sizeof (mbstate_t)); 315 while (hlen >= nlen) 316 { 317 if (memcmp (haystack, needle, nlen) == 0) 318 return (char *) haystack; 319 step = mbrlen (haystack, hlen, &mbstate); 320 if (step <= 0) 321 break; 322 haystack += step; 323 hlen -= step; 324 } 325 return NULL; 326 } 327#endif 328 return strstr (haystack, needle); 329} 330 331static size_t 332get_line_max(void) 333{ 334 long val; 335#ifdef _SC_LINE_MAX 336 val = sysconf(_SC_LINE_MAX); 337#else 338 val = -1; 339#endif 340 341 if (val > 0) 342 return val; 343 344 /* either _SC_LINE_MAX was not available or 345 * there is no particular limit. 346 */ 347#ifdef LINE_MAX 348 val = LINE_MAX; 349#endif 350 351 if (val > 0) 352 return val; 353 354 return 2048L; /* a reasonable guess. */ 355} 356 357 358size_t 359bc_get_arg_max(void) 360{ 361 long val; 362 363 /* We may resort to using LONG_MAX, so check it fits. */ 364 /* XXX: better to do a compile-time check */ 365 assert( (~(size_t)0) >= LONG_MAX); 366 367#ifdef _SC_ARG_MAX 368 val = sysconf(_SC_ARG_MAX); 369#else 370 val = -1; 371#endif 372 373 if (val > 0) 374 return val; 375 376 /* either _SC_ARG_MAX was not available or 377 * there is no particular limit. 378 */ 379#ifdef ARG_MAX 380 val = ARG_MAX; 381#endif 382 383 if (val > 0) 384 return val; 385 386 /* The value returned by this function bounds the 387 * value applied as the ceiling for the -s option. 388 * Hence it the system won't tell us what its limit 389 * is, we allow the user to specify more or less 390 * whatever value they like. 391 */ 392 return LONG_MAX; 393} 394 395 396static int cb_exec_noop(const struct buildcmd_control *ctl, 397 struct buildcmd_state *state) 398{ 399 /* does nothing. */ 400 (void) ctl; 401 (void) state; 402 403 return 0; 404} 405 406 407/* Return how much of ARG_MAX is used by the environment. */ 408size_t 409bc_size_of_environment (void) 410{ 411 size_t len = 0u; 412 char **envp = environ; 413 414 while (*envp) 415 len += strlen (*envp++) + 1; 416 417 return len; 418} 419 420 421enum BC_INIT_STATUS 422bc_init_controlinfo(struct buildcmd_control *ctl) 423{ 424 size_t size_of_environment = bc_size_of_environment(); 425 size_t arg_max; 426 427 ctl->posix_arg_size_min = get_line_max(); 428 arg_max = bc_get_arg_max(); 429 430 /* POSIX.2 requires subtracting 2048. */ 431 assert(arg_max > 2048u); /* XXX: this is an external condition, should not check it with assert. */ 432 ctl->posix_arg_size_max = (arg_max - 2048); 433 434 ctl->exit_if_size_exceeded = 0; 435 436 /* Take the size of the environment into account. */ 437 if (size_of_environment > ctl->posix_arg_size_max) 438 { 439 return BC_INIT_ENV_TOO_BIG; 440 } 441 else 442 { 443 ctl->posix_arg_size_max - size_of_environment; 444 } 445 446 /* need to subtract 2 on the following line - for Linux/PPC */ 447 ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u; 448 assert(ctl->max_arg_count > 0); 449 ctl->rplen = 0u; 450 ctl->replace_pat = NULL; 451 ctl->initial_argc = 0; 452 ctl->exec_callback = cb_exec_noop; 453 ctl->lines_per_exec = 0; 454 ctl->args_per_exec = 0; 455 456 /* Set the initial value of arg_max to the largest value we can 457 * tolerate. 458 */ 459 ctl->arg_max = ctl->posix_arg_size_max; 460 461 return BC_INIT_OK; 462} 463 464void 465bc_use_sensible_arg_max(struct buildcmd_control *ctl) 466{ 467 size_t env_size = bc_size_of_environment(); 468 const size_t arg_size = (128u * 1024u) + env_size; 469 470 /* Check against the upper and lower limits. */ 471 if (arg_size > ctl->posix_arg_size_max) 472 ctl->arg_max = ctl->posix_arg_size_max - env_size; 473 else if (arg_size < ctl->posix_arg_size_min) 474 ctl->arg_max = ctl->posix_arg_size_min; 475 else 476 ctl->arg_max = arg_size; 477} 478 479 480 481 482void 483bc_init_state(const struct buildcmd_control *ctl, 484 struct buildcmd_state *state, 485 void *context) 486{ 487 state->cmd_argc = 0; 488 state->cmd_argv_chars = 0; 489 state->cmd_argv = NULL; 490 state->cmd_argv_alloc = 0; 491 492 /* XXX: the following memory allocation is inadvisable on systems 493 * with no ARG_MAX, because ctl->arg_max may actually be close to 494 * LONG_MAX. Adding one to it is safe though because earlier we 495 * subtracted 2048. 496 */ 497 assert(ctl->arg_max <= (LONG_MAX - 2048L)); 498 state->argbuf = (char *) xmalloc (ctl->arg_max + 1u); 499 500 state->cmd_argv_chars = state->cmd_initial_argv_chars = 0; 501 state->todo = 0; 502 state->usercontext = context; 503} 504 505void 506bc_clear_args(const struct buildcmd_control *ctl, 507 struct buildcmd_state *state) 508{ 509 state->cmd_argc = ctl->initial_argc; 510 state->cmd_argv_chars = state->cmd_initial_argv_chars; 511 state->todo = 0; 512} 513 514