static WORD_LIST *
expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
     WORD_DESC *word;
     int quoted, isexp;
     int *contains_dollar_at;
     int *expanded_something;
{
  WORD_LIST *list;
  WORD_DESC *tword;

  /* The intermediate string that we build while expanding. */
  char *istring;

  /* The current size of the above object. */
  size_t istring_size;

  /* Index into ISTRING. */
  int istring_index;

  /* Temporary string storage. */
  char *temp, *temp1;

  /* The text of WORD. */
  register char *string;

  /* The size of STRING. */
  size_t string_size;

  /* The index into STRING. */
  int sindex;

  /* This gets 1 if we see a $@ while quoted. */
  int quoted_dollar_at;

  /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
     whether WORD contains no quoting characters, a partially quoted
     string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
  int quoted_state;

  /* State flags */
  int had_quoted_null;
  int has_dollar_at, temp_has_dollar_at;
  int split_on_spaces;
  int tflag;
  int pflags;			/* flags passed to param_expand */
  int mb_cur_max;

  int assignoff;		/* If assignment, offset of `=' */

  register unsigned char c;	/* Current character. */
  int t_index;			/* For calls to string_extract_xxx. */

  char twochars[2];

  DECLARE_MBSTATE;

  /* OK, let's see if we can optimize a common idiom: "$@" */
  if (STREQ (word->word, "\"$@\"") &&
      (word->flags == (W_HASDOLLAR|W_QUOTED)) &&
      dollar_vars[1])		/* XXX - check IFS here as well? */
    {
      if (contains_dollar_at)
	*contains_dollar_at = 1;
      if (expanded_something)
	*expanded_something = 1;
      if (cached_quoted_dollar_at)
	return (copy_word_list (cached_quoted_dollar_at));
      list = list_rest_of_args ();
      list = quote_list (list);
      cached_quoted_dollar_at = copy_word_list (list);
      return (list);
    }

  istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
  istring[istring_index = 0] = '\0';
  quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
  split_on_spaces = 0;
  quoted_state = UNQUOTED;

  string = word->word;
  if (string == 0)
    goto finished_with_string;
  mb_cur_max = MB_CUR_MAX;

  /* Don't need the string length for the SADD... and COPY_ macros unless
     multibyte characters are possible. */
  string_size = (mb_cur_max > 1) ? strlen (string) : 1;

  if (contains_dollar_at)
    *contains_dollar_at = 0;

  assignoff = -1;

  /* Begin the expansion. */

  for (sindex = 0; ;)
    {
      c = string[sindex];

      /* Case on top-level character. */
      switch (c)
	{
	case '\0':
	  goto finished_with_string;

	case CTLESC:
	  sindex++;
#if HANDLE_MULTIBYTE
	  if (mb_cur_max > 1 && string[sindex])
	    {
	      SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
	    }
	  else
#endif
	    {
	      temp = (char *)xmalloc (3);
	      temp[0] = CTLESC;
	      temp[1] = c = string[sindex];
	      temp[2] = '\0';
	    }

dollar_add_string:
	  if (string[sindex])
	    sindex++;

add_string:
	  if (temp)
	    {
	      istring = sub_append_string (temp, istring, &istring_index, &istring_size);
	      temp = (char *)0;
	    }

	  break;

#if defined (PROCESS_SUBSTITUTION)
	  /* Process substitution. */
	case '<':
	case '>':
	  {
	    /* bash-4.4/bash-5.0
	       XXX - technically this should only be expanded at the start
	       of a word */
	    if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
	      {
		sindex--;	/* add_character: label increments sindex */
		goto add_character;
	      }
	    else
	      t_index = sindex + 1; /* skip past both '<' and LPAREN */

	    temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index, 0); /*))*/
	    sindex = t_index;

	    /* If the process substitution specification is `<()', we want to
	       open the pipe for writing in the child and produce output; if
	       it is `>()', we want to open the pipe for reading in the child
	       and consume input. */
	    temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;

	    FREE (temp1);

	    goto dollar_add_string;
	  }
#endif /* PROCESS_SUBSTITUTION */

	case '=':
	  /* Posix.2 section 3.6.1 says that tildes following `=' in words
	     which are not assignment statements are not expanded.  If the
	     shell isn't in posix mode, though, we perform tilde expansion
	     on `likely candidate' unquoted assignment statements (flags
	     include W_ASSIGNMENT but not W_QUOTED).  A likely candidate
	     contains an unquoted :~ or =~.  Something to think about: we
	     now have a flag that says  to perform tilde expansion on arguments
	     to `assignment builtins' like declare and export that look like
	     assignment statements.  We now do tilde expansion on such words
	     even in POSIX mode. */
	  if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
	    {
	      if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
		goto add_ifs_character;
	      else
		goto add_character;
	    }
	  /* If we're not in posix mode or forcing assignment-statement tilde
	     expansion, note where the `=' appears in the word and prepare to
	     do tilde expansion following the first `='. */
	  if ((word->flags & W_ASSIGNMENT) &&
	      (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
	      assignoff == -1 && sindex > 0)
	    assignoff = sindex;
	  if (sindex == assignoff && string[sindex+1] == '~')	/* XXX */
	    word->flags |= W_ITILDE;
#if 0
	  else if ((word->flags & W_ASSIGNMENT) &&
		   (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
		   string[sindex+1] == '~')
	    word->flags |= W_ITILDE;
#endif

	  /* XXX - bash-4.4/bash-5.0 */
	  if (word->flags & W_ASSIGNARG)
	    word->flags |= W_ASSIGNRHS;		/* affects $@ */

	  if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
	    goto add_ifs_character;
	  else
	    goto add_character;

	case ':':
	  if (word->flags & W_NOTILDE)
	    {
	      if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
		goto add_ifs_character;
	      else
		goto add_character;
	    }

	  if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
	      string[sindex+1] == '~')
	    word->flags |= W_ITILDE;

	  if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
	    goto add_ifs_character;
	  else
	    goto add_character;

	case '~':
	  /* If the word isn't supposed to be tilde expanded, or we're not
	     at the start of a word or after an unquoted : or = in an
	     assignment statement, we don't do tilde expansion.  If we don't want
	     tilde expansion when expanding words to be passed to the arithmetic
	     evaluator, remove the check for Q_ARITH. */
	  if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
	      (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
	      ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0)))
	    {
	      word->flags &= ~W_ITILDE;
	      if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
		goto add_ifs_character;
	      else
		goto add_character;
	    }

	  if (word->flags & W_ASSIGNRHS)
	    tflag = 2;
	  else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
	    tflag = 1;
	  else
	    tflag = 0;

	  temp = bash_tilde_find_word (string + sindex, tflag, &t_index);

	  word->flags &= ~W_ITILDE;

	  if (temp && *temp && t_index > 0)
	    {
	      temp1 = bash_tilde_expand (temp, tflag);
	      if  (temp1 && *temp1 == '~' && STREQ (temp, temp1))
		{
		  FREE (temp);
		  FREE (temp1);
		  goto add_character;		/* tilde expansion failed */
		}
	      free (temp);
	      temp = temp1;
	      sindex += t_index;
	      goto add_quoted_string;		/* XXX was add_string */
	    }
	  else
	    {
	      FREE (temp);
	      goto add_character;
	    }

	case '$':
	  if (expanded_something)
	    *expanded_something = 1;

	  temp_has_dollar_at = 0;
	  pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
	  if (word->flags & W_NOSPLIT2)
	    pflags |= PF_NOSPLIT2;
	  if (word->flags & W_ASSIGNRHS)
	    pflags |= PF_ASSIGNRHS;
	  if (word->flags & W_COMPLETE)
	    pflags |= PF_COMPLETE;
	  tword = param_expand (string, &sindex, quoted, expanded_something,
			       &temp_has_dollar_at, &quoted_dollar_at,
			       &had_quoted_null, pflags);
	  has_dollar_at += temp_has_dollar_at;
	  split_on_spaces += (tword->flags & W_SPLITSPACE);

	  if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
	    {
	      free (string);
	      free (istring);
	      return ((tword == &expand_wdesc_error) ? &expand_word_error
						     : &expand_word_fatal);
	    }
	  if (contains_dollar_at && has_dollar_at)
	    *contains_dollar_at = 1;

	  if (tword && (tword->flags & W_HASQUOTEDNULL))
	    had_quoted_null = 1;

	  temp = tword ? tword->word : (char *)NULL;
	  dispose_word_desc (tword);

	  /* Kill quoted nulls; we will add them back at the end of
	     expand_word_internal if nothing else in the string */
	  if (had_quoted_null && temp && QUOTED_NULL (temp))
	    {
	      FREE (temp);
	      temp = (char *)NULL;
	    }

	  goto add_string;
	  break;

	case '`':		/* Backquoted command substitution. */
	  {
	    t_index = sindex++;

	    temp = string_extract (string, &sindex, "`", SX_REQMATCH);
	    /* The test of sindex against t_index is to allow bare instances of
	       ` to pass through, for backwards compatibility. */
	    if (temp == &extract_string_error || temp == &extract_string_fatal)
	      {
		if (sindex - 1 == t_index)
		  {
		    sindex = t_index;
		    goto add_character;
		  }
		last_command_exit_value = EXECUTION_FAILURE;
		report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
		free (string);
		free (istring);
		return ((temp == &extract_string_error) ? &expand_word_error
							: &expand_word_fatal);
	      }

	    if (expanded_something)
	      *expanded_something = 1;

	    if (word->flags & W_NOCOMSUB)
	      /* sindex + 1 because string[sindex] == '`' */
	      temp1 = substring (string, t_index, sindex + 1);
	    else
	      {
		de_backslash (temp);
		tword = command_substitute (temp, quoted);
		temp1 = tword ? tword->word : (char *)NULL;
		if (tword)
		  dispose_word_desc (tword);
	      }
	    FREE (temp);
	    temp = temp1;
	    goto dollar_add_string;
	  }

	case '\\':
	  if (string[sindex + 1] == '\n')
	    {
	      sindex += 2;
	      continue;
	    }

	  c = string[++sindex];

	  if (quoted & Q_HERE_DOCUMENT)
	    tflag = CBSHDOC;
	  else if (quoted & Q_DOUBLE_QUOTES)
	    tflag = CBSDQUOTE;
	  else
	    tflag = 0;

	  /* From Posix discussion on austin-group list:  Backslash escaping
	     a } in ${...} is removed.  Issue 0000221 */
	  if ((quoted & Q_DOLBRACE) && c == RBRACE)
	    {
	      SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
	    }
	  /* This is the fix for " $@\ " */
	  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0) && isexp == 0 && isifs (c))
	    {
	      RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
				      DEFAULT_ARRAY_SIZE);
	      istring[istring_index++] = CTLESC;
	      istring[istring_index++] = '\\';
	      istring[istring_index] = '\0';

	      SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
	    }
	  else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
	    {
	      SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
	    }
	  else if (c == 0)
	    {
	      c = CTLNUL;
	      sindex--;		/* add_character: label increments sindex */
	      goto add_character;
	    }
	  else
	    {
	      SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
	    }

	  sindex++;
add_twochars:
	  /* BEFORE jumping here, we need to increment sindex if appropriate */
	  RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
				  DEFAULT_ARRAY_SIZE);
	  istring[istring_index++] = twochars[0];
	  istring[istring_index++] = twochars[1];
	  istring[istring_index] = '\0';

	  break;

	case '"':
	  if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0))
	    goto add_character;

	  t_index = ++sindex;
	  temp = string_extract_double_quoted (string, &sindex, (word->flags & W_COMPLETE) ? SX_COMPLETE : 0);

	  /* If the quotes surrounded the entire string, then the
	     whole word was quoted. */
	  quoted_state = (t_index == 1 && string[sindex] == '\0')
			    ? WHOLLY_QUOTED
			    : PARTIALLY_QUOTED;

	  if (temp && *temp)
	    {
	      tword = alloc_word_desc ();
	      tword->word = temp;

	      /* XXX - bash-4.4/bash-5.0 */
	      if (word->flags & W_ASSIGNARG)
		tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS);	/* affects $@ */
	      if (word->flags & W_COMPLETE)
		tword->flags |= W_COMPLETE;	/* for command substitutions */

	      temp = (char *)NULL;

	      temp_has_dollar_at = 0;	/* XXX */
	      /* Need to get W_HASQUOTEDNULL flag through this function. */
	      list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
	      has_dollar_at += temp_has_dollar_at;

	      if (list == &expand_word_error || list == &expand_word_fatal)
		{
		  free (istring);
		  free (string);
		  /* expand_word_internal has already freed temp_word->word
		     for us because of the way it prints error messages. */
		  tword->word = (char *)NULL;
		  dispose_word (tword);
		  return list;
		}

	      dispose_word (tword);

	      /* "$@" (a double-quoted dollar-at) expands into nothing,
		 not even a NULL word, when there are no positional
		 parameters. */
	      if (list == 0 && temp_has_dollar_at)	/* XXX - was has_dollar_at */
		{
		  quoted_dollar_at++;
		  break;
		}

	      /* If we get "$@", we know we have expanded something, so we
		 need to remember it for the final split on $IFS.  This is
		 a special case; it's the only case where a quoted string
		 can expand into more than one word.  It's going to come back
		 from the above call to expand_word_internal as a list with
		 a single word, in which all characters are quoted and
		 separated by blanks.  What we want to do is to turn it back
		 into a list for the next piece of code. */
	      if (list)
		dequote_list (list);

	      if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
		had_quoted_null = 1;		/* XXX */

	      if (temp_has_dollar_at)		/* XXX - was has_dollar_at */
		{
		  quoted_dollar_at++;
		  if (contains_dollar_at)
		    *contains_dollar_at = 1;
		  if (expanded_something)
		    *expanded_something = 1;
		}
	    }
	  else
	    {
	      /* What we have is "".  This is a minor optimization. */
	      FREE (temp);
	      list = (WORD_LIST *)NULL;
	    }

	  /* The code above *might* return a list (consider the case of "$@",
	     where it returns "$1", "$2", etc.).  We can't throw away the
	     rest of the list, and we have to make sure each word gets added
	     as quoted.  We test on tresult->next:  if it is non-NULL, we
	     quote the whole list, save it to a string with string_list, and
	     add that string. We don't need to quote the results of this
	     (and it would be wrong, since that would quote the separators
	     as well), so we go directly to add_string. */
	  if (list)
	    {
	      if (list->next)
		{
		  /* Testing quoted_dollar_at makes sure that "$@" is
		     split correctly when $IFS does not contain a space. */
		  temp = quoted_dollar_at
				? string_list_dollar_at (list, Q_DOUBLE_QUOTES, 0)
				: string_list (quote_list (list));
		  dispose_words (list);
		  goto add_string;
		}
	      else
		{
		  temp = savestring (list->word->word);
		  tflag = list->word->flags;
		  dispose_words (list);

		  /* If the string is not a quoted null string, we want
		     to remove any embedded unquoted CTLNUL characters.
		     We do not want to turn quoted null strings back into
		     the empty string, though.  We do this because we
		     want to remove any quoted nulls from expansions that
		     contain other characters.  For example, if we have
		     x"$*"y or "x$*y" and there are no positional parameters,
		     the $* should expand into nothing. */
		  /* We use the W_HASQUOTEDNULL flag to differentiate the
		     cases:  a quoted null character as above and when
		     CTLNUL is contained in the (non-null) expansion
		     of some variable.  We use the had_quoted_null flag to
		     pass the value through this function to its caller. */
		  if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
		    remove_quoted_nulls (temp);	/* XXX */
		}
	    }
	  else
	    temp = (char *)NULL;

	  /* We do not want to add quoted nulls to strings that are only
	     partially quoted; we can throw them away.  The exception to
	     this is when we are going to be performing word splitting,
	     since we have to preserve a null argument if the next character
	     will cause word splitting. */
	  if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
	    continue;

	add_quoted_string:

	  if (temp)
	    {
	      temp1 = temp;
	      temp = quote_string (temp);
	      free (temp1);
	      goto add_string;
	    }
	  else
	    {
	      /* Add NULL arg. */
	      c = CTLNUL;
	      sindex--;		/* add_character: label increments sindex */
	      goto add_character;
	    }

	  /* break; */

	case '\'':
	  if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
	    goto add_character;

	  t_index = ++sindex;
	  temp = string_extract_single_quoted (string, &sindex);

	  /* If the entire STRING was surrounded by single quotes,
	     then the string is wholly quoted. */
	  quoted_state = (t_index == 1 && string[sindex] == '\0')
			    ? WHOLLY_QUOTED
			    : PARTIALLY_QUOTED;

	  /* If all we had was '', it is a null expansion. */
	  if (*temp == '\0')
	    {
	      free (temp);
	      temp = (char *)NULL;
	    }
	  else
	    remove_quoted_escapes (temp);	/* ??? */

	  /* We do not want to add quoted nulls to strings that are only
	     partially quoted; such nulls are discarded.  See above for the
	     exception, which is when the string is going to be split. */
	  if (temp == 0 && (quoted_state == PARTIALLY_QUOTED) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
	    continue;

	  /* If we have a quoted null expansion, add a quoted NULL to istring. */
	  if (temp == 0)
	    {
	      c = CTLNUL;
	      sindex--;		/* add_character: label increments sindex */
	      goto add_character;
	    }
	  else
	    goto add_quoted_string;

	  /* break; */

	default:
	  /* This is the fix for " $@ " */
	add_ifs_character:
	  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0))
	    {
	      if (string[sindex])	/* from old goto dollar_add_string */
		sindex++;
	      if (c == 0)
		{
		  c = CTLNUL;
		  goto add_character;
		}
	      else
		{
#if HANDLE_MULTIBYTE
		  if (mb_cur_max > 1)
		    sindex--;

		  if (mb_cur_max > 1)
		    {
		      SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
		    }
		  else
#endif
		    {
		      twochars[0] = CTLESC;
		      twochars[1] = c;
		      goto add_twochars;
		    }
		}
	    }

	  SADD_MBCHAR (temp, string, sindex, string_size);

	add_character:
	  RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
				  DEFAULT_ARRAY_SIZE);
	  istring[istring_index++] = c;
	  istring[istring_index] = '\0';

	  /* Next character. */
	  sindex++;
	}
    }

finished_with_string:
  /* OK, we're ready to return.  If we have a quoted string, and
     quoted_dollar_at is not set, we do no splitting at all; otherwise
     we split on ' '.  The routines that call this will handle what to
     do if nothing has been expanded. */

  /* Partially and wholly quoted strings which expand to the empty
     string are retained as an empty arguments.  Unquoted strings
     which expand to the empty string are discarded.  The single
     exception is the case of expanding "$@" when there are no
     positional parameters.  In that case, we discard the expansion. */

  /* Because of how the code that handles "" and '' in partially
     quoted strings works, we need to make ISTRING into a QUOTED_NULL
     if we saw quoting characters, but the expansion was empty.
     "" and '' are tossed away before we get to this point when
     processing partially quoted strings.  This makes "" and $xxx""
     equivalent when xxx is unset.  We also look to see whether we
     saw a quoted null from a ${} expansion and add one back if we
     need to. */

  /* If we expand to nothing and there were no single or double quotes
     in the word, we throw it away.  Otherwise, we return a NULL word.
     The single exception is for $@ surrounded by double quotes when
     there are no positional parameters.  In that case, we also throw
     the word away. */

  if (*istring == '\0')
    {
      if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
	{
	  istring[0] = CTLNUL;
	  istring[1] = '\0';
	  tword = make_bare_word (istring);
	  tword->flags |= W_HASQUOTEDNULL;		/* XXX */
	  list = make_word_list (tword, (WORD_LIST *)NULL);
	  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
	    tword->flags |= W_QUOTED;
	}
      /* According to sh, ksh, and Posix.2, if a word expands into nothing
	 and a double-quoted "$@" appears anywhere in it, then the entire
	 word is removed. */
      /* XXX - exception appears to be that quoted null strings result in
	 null arguments */
      else  if (quoted_state == UNQUOTED || quoted_dollar_at)
	list = (WORD_LIST *)NULL;
#if 0
      else
	{
	  tword = make_bare_word (istring);
	  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
	    tword->flags |= W_QUOTED;
	  list = make_word_list (tword, (WORD_LIST *)NULL);
	}
#else
      else
	list = (WORD_LIST *)NULL;
#endif
    }
  else if (word->flags & W_NOSPLIT)
    {
      tword = make_bare_word (istring);
      if (word->flags & W_ASSIGNMENT)
	tword->flags |= W_ASSIGNMENT;	/* XXX */
      if (word->flags & W_COMPASSIGN)
	tword->flags |= W_COMPASSIGN;	/* XXX */
      if (word->flags & W_NOGLOB)
	tword->flags |= W_NOGLOB;	/* XXX */
      if (word->flags & W_NOBRACE)
	tword->flags |= W_NOBRACE;	/* XXX */
      if (word->flags & W_NOEXPAND)
	tword->flags |= W_NOEXPAND;	/* XXX */
      if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
	tword->flags |= W_QUOTED;
      if (had_quoted_null && QUOTED_NULL (istring))
	tword->flags |= W_HASQUOTEDNULL;
      list = make_word_list (tword, (WORD_LIST *)NULL);
    }
  else
    {
      char *ifs_chars;
      char *tstring;

      ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;

      /* If we have $@, we need to split the results no matter what.  If
	 IFS is unset or NULL, string_list_dollar_at has separated the
	 positional parameters with a space, so we split on space (we have
	 set ifs_chars to " \t\n" above if ifs is unset).  If IFS is set,
	 string_list_dollar_at has separated the positional parameters
	 with the first character of $IFS, so we split on $IFS.  If
	 SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
	 unset or null, and we want to make sure that we split on spaces
	 regardless of what else has happened to IFS since the expansion,
	 or we expanded "$@" with IFS null and we need to split the positional
	 parameters into separate words. */
      if (split_on_spaces)
	list = list_string (istring, " ", 1);	/* XXX quoted == 1? */
      /* If we have $@ (has_dollar_at != 0) and we are in a context where we
	 don't want to split the result (W_NOSPLIT2), and we are not quoted,
	 we have already separated the arguments with the first character of
	 $IFS.  In this case, we want to return a list with a single word
	 with the separator possibly replaced with a space (it's what other
	 shells seem to do).
	 quoted_dollar_at is internal to this function and is set if we are
	 passed an argument that is unquoted (quoted == 0) but we encounter a
	 double-quoted $@ while expanding it. */
      else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
	{
	  /* Only split and rejoin if we have to */
	  if (*ifs_chars && *ifs_chars != ' ')
	    {
	      list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
	      tstring = string_list (list);
	    }
	  else
	    tstring = istring;
	  tword = make_bare_word (tstring);
	  if (tstring != istring)
	    free (tstring);
	  goto set_word_flags;
	}
      /* This is the attempt to make $* in an assignment context (a=$*) and
	 array variables subscripted with * in an assignment context (a=${foo[*]})
	 behave similarly.  It has side effects that, though they increase
	 compatibility with other shells, are not backwards compatible. */
#if 0
      else if (has_dollar_at && quoted == 0 && ifs_chars && (word->flags & W_ASSIGNRHS))
	{
	  tword = make_bare_word (istring);
	  goto set_word_flags;
	}
#endif
      else if (has_dollar_at && ifs_chars)
	list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
      else
	{
	  tword = make_bare_word (istring);
set_word_flags:
	  if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
	    tword->flags |= W_QUOTED;
	  if (word->flags & W_ASSIGNMENT)
	    tword->flags |= W_ASSIGNMENT;
	  if (word->flags & W_COMPASSIGN)
	    tword->flags |= W_COMPASSIGN;
	  if (word->flags & W_NOGLOB)
	    tword->flags |= W_NOGLOB;
	  if (word->flags & W_NOBRACE)
	    tword->flags |= W_NOBRACE;
	  if (word->flags & W_NOEXPAND)
	    tword->flags |= W_NOEXPAND;
	  if (had_quoted_null && QUOTED_NULL (istring))
	    tword->flags |= W_HASQUOTEDNULL;	/* XXX */
	  list = make_word_list (tword, (WORD_LIST *)NULL);
	}
    }

  free (istring);
  return (list);


static void test_qga_file_ops(gconstpointer fix) { const TestFixture *fixture = fix; const unsigned char helloworld[] = "Hello World!\n"; const char *b64; gchar *cmd, *path, *enc; unsigned char *dec; QDict *ret, *val; int64_t id, eof; gsize count; FILE *f; char tmp[100]; /* open */ ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open'," " 'arguments': { 'path': 'foo', 'mode': 'w+' } }"); g_assert_nonnull(ret); qmp_assert_no_error(ret); id = qdict_get_int(ret, "return"); QDECREF(ret); enc = g_base64_encode(helloworld, sizeof(helloworld)); /* write */ cmd = g_strdup_printf("{'execute': 'guest-file-write'," " 'arguments': { 'handle': %" PRId64 "," " 'buf-b64': '%s' } }", id, enc); ret = qmp_fd(fixture->fd, cmd); g_assert_nonnull(ret); qmp_assert_no_error(ret); val = qdict_get_qdict(ret, "return"); count = qdict_get_int(val, "count"); eof = qdict_get_bool(val, "eof"); g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert_cmpint(eof, ==, 0); QDECREF(ret); g_free(cmd); /* flush */ cmd = g_strdup_printf("{'execute': 'guest-file-flush'," " 'arguments': {'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); QDECREF(ret); g_free(cmd); /* close */ cmd = g_strdup_printf("{'execute': 'guest-file-close'," " 'arguments': {'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); QDECREF(ret); g_free(cmd); /* check content */ path = g_build_filename(fixture->test_dir, "foo", NULL); f = fopen(path, "r"); g_assert_nonnull(f); count = fread(tmp, 1, sizeof(tmp), f); g_assert_cmpint(count, ==, sizeof(helloworld)); tmp[count] = 0; g_assert_cmpstr(tmp, ==, (char *)helloworld); fclose(f); /* open */ ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open'," " 'arguments': { 'path': 'foo', 'mode': 'r' } }"); g_assert_nonnull(ret); qmp_assert_no_error(ret); id = qdict_get_int(ret, "return"); QDECREF(ret); /* read */ cmd = g_strdup_printf("{'execute': 'guest-file-read'," " 'arguments': { 'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); val = qdict_get_qdict(ret, "return"); count = qdict_get_int(val, "count"); eof = qdict_get_bool(val, "eof"); b64 = qdict_get_str(val, "buf-b64"); g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert(eof); g_assert_cmpstr(b64, ==, enc); QDECREF(ret); g_free(cmd); g_free(enc); /* read eof */ cmd = g_strdup_printf("{'execute': 'guest-file-read'," " 'arguments': { 'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); val = qdict_get_qdict(ret, "return"); count = qdict_get_int(val, "count"); eof = qdict_get_bool(val, "eof"); b64 = qdict_get_str(val, "buf-b64"); g_assert_cmpint(count, ==, 0); g_assert(eof); g_assert_cmpstr(b64, ==, ""); QDECREF(ret); g_free(cmd); /* seek */ cmd = g_strdup_printf("{'execute': 'guest-file-seek'," " 'arguments': { 'handle': %" PRId64 ", " " 'offset': %d, 'whence': '%s' } }", id, 6, "set"); ret = qmp_fd(fixture->fd, cmd); qmp_assert_no_error(ret); val = qdict_get_qdict(ret, "return"); count = qdict_get_int(val, "position"); eof = qdict_get_bool(val, "eof"); g_assert_cmpint(count, ==, 6); g_assert(!eof); QDECREF(ret); g_free(cmd); /* partial read */ cmd = g_strdup_printf("{'execute': 'guest-file-read'," " 'arguments': { 'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); val = qdict_get_qdict(ret, "return"); count = qdict_get_int(val, "count"); eof = qdict_get_bool(val, "eof"); b64 = qdict_get_str(val, "buf-b64"); g_assert_cmpint(count, ==, sizeof(helloworld) - 6); g_assert(eof); dec = g_base64_decode(b64, &count); g_assert_cmpint(count, ==, sizeof(helloworld) - 6); g_assert_cmpmem(dec, count, helloworld + 6, sizeof(helloworld) - 6); g_free(dec); QDECREF(ret); g_free(cmd); /* close */ cmd = g_strdup_printf("{'execute': 'guest-file-close'," " 'arguments': {'handle': %" PRId64 "} }", id); ret = qmp_fd(fixture->fd, cmd); QDECREF(ret); g_free(cmd); }


static bool vexpress_cfgctrl_write(arm_sysctl_state *s, unsigned int dcc, unsigned int function, unsigned int site, unsigned int position, unsigned int device, uint32_t val) { /* We don't support anything other than DCC 0, board stack position 0 * or sites other than motherboard/daughterboard: */ if (dcc != 0 || position != 0 || (site != SYS_CFG_SITE_MB && site != SYS_CFG_SITE_DB1)) { goto cfgctrl_unimp; } switch (function) { case SYS_CFG_OSC: if (site == SYS_CFG_SITE_MB && device < sizeof(s->mb_clock)) { /* motherboard clock */ s->mb_clock[device] = val; return true; } if (site == SYS_CFG_SITE_DB1 && device < s->db_num_clocks) { /* daughterboard clock */ s->db_clock[device] = val; return true; } break; case SYS_CFG_MUXFPGA: if (site == SYS_CFG_SITE_MB && device == 0) { /* Select whether video output comes from motherboard * or daughterboard: log and ignore as QEMU doesn't * support this. */ qemu_log_mask(LOG_UNIMP, "arm_sysctl: selection of video output " "not supported, ignoring\n"); return true; } break; case SYS_CFG_SHUTDOWN: if (site == SYS_CFG_SITE_MB && device == 0) { qemu_system_shutdown_request(); return true; } break; case SYS_CFG_REBOOT: if (site == SYS_CFG_SITE_MB && device == 0) { qemu_system_reset_request(); return true; } break; case SYS_CFG_DVIMODE: if (site == SYS_CFG_SITE_MB && device == 0) { /* Selecting DVI mode is meaningless for QEMU: we will * always display the output correctly according to the * pixel height/width programmed into the CLCD controller. */ return true; } default: break; } cfgctrl_unimp: qemu_log_mask(LOG_UNIMP, "arm_sysctl: Unimplemented SYS_CFGCTRL write of function " "0x%x DCC 0x%x site 0x%x position 0x%x device 0x%x\n", function, dcc, site, position, device); return false; }


static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
{
#ifdef CONFIG_TIMER_STATS
	timer->start_site = NULL;
#endif
}


static void do_init_timer(struct timer_list *timer, unsigned int flags,
			  const char *name, struct lock_class_key *key)
{
	timer->entry.pprev = NULL;
	timer->flags = flags | raw_smp_processor_id();
#ifdef CONFIG_TIMER_STATS
	timer->start_site = NULL;
	timer->start_pid = -1;
	memset(timer->start_comm, 0, TASK_COMM_LEN);
#endif
	lockdep_init_map(&timer->lockdep_map, name, key, 0);
}


void add_timer_on(struct timer_list *timer, int cpu)
{
	struct timer_base *new_base, *base;
	unsigned long flags;

	timer_stats_timer_set_start_info(timer);
	BUG_ON(timer_pending(timer) || !timer->function);

	new_base = get_timer_cpu_base(timer->flags, cpu);

	/*
	 * If @timer was on a different CPU, it should be migrated with the
	 * old base locked to prevent other operations proceeding with the
	 * wrong base locked.  See lock_timer_base().
	 */
	base = lock_timer_base(timer, &flags);
	if (base != new_base) {
		timer->flags |= TIMER_MIGRATING;

		spin_unlock(&base->lock);
		base = new_base;
		spin_lock(&base->lock);
		WRITE_ONCE(timer->flags,
			   (timer->flags & ~TIMER_BASEMASK) | cpu);
	}

	debug_activate(timer, timer->expires);
	internal_add_timer(base, timer);
	spin_unlock_irqrestore(&base->lock, flags);
}


static void ohci_td_pkt ( const char * msg , const uint8_t * buf , size_t len ) {
 }


static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAStatus vas; int i, n, err; VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; VAConfigAttrib attr[] = { { VAConfigAttribRateControl }, { VAConfigAttribEncMaxRefFrames }, }; n = vaMaxNumProfiles(ctx->hwctx->display); profiles = av_malloc_array(n, sizeof(VAProfile)); if (!profiles) { err = AVERROR(ENOMEM); goto fail; } vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(ENOSYS); goto fail; } for (i = 0; i < n; i++) { if (profiles[i] == ctx->va_profile) break; } if (i >= n) { av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n", ctx->va_profile); err = AVERROR(ENOSYS); goto fail; } n = vaMaxNumEntrypoints(ctx->hwctx->display); entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); if (!entrypoints) { err = AVERROR(ENOMEM); goto fail; } vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile, entrypoints, &n); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for " "profile %u: %d (%s).\n", ctx->va_profile, vas, vaErrorStr(vas)); err = AVERROR(ENOSYS); goto fail; } for (i = 0; i < n; i++) { if (entrypoints[i] == ctx->va_entrypoint) break; } if (i >= n) { av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found " "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint); err = AVERROR(ENOSYS); goto fail; } vas = vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile, ctx->va_entrypoint, attr, FF_ARRAY_ELEMS(attr)); if (vas != VA_STATUS_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to fetch config " "attributes: %d (%s).\n", vas, vaErrorStr(vas)); return AVERROR(EINVAL); } for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) { if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) { // Unfortunately we have to treat this as "don't know" and hope // for the best, because the Intel MJPEG encoder returns this // for all the interesting attributes. continue; } switch (attr[i].type) { case VAConfigAttribRateControl: if (!(ctx->va_rc_mode & attr[i].value)) { av_log(avctx, AV_LOG_ERROR, "Rate control mode is not " "supported: %x\n", attr[i].value); err = AVERROR(EINVAL); goto fail; } break; case VAConfigAttribEncMaxRefFrames: { unsigned int ref_l0 = attr[i].value & 0xffff; unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff; if (avctx->gop_size > 1 && ref_l0 < 1) { av_log(avctx, AV_LOG_ERROR, "P frames are not " "supported (%x).\n", attr[i].value); err = AVERROR(EINVAL); goto fail; } if (avctx->max_b_frames > 0 && ref_l1 < 1) { av_log(avctx, AV_LOG_ERROR, "B frames are not " "supported (%x).\n", attr[i].value); err = AVERROR(EINVAL); goto fail; } } break; } } err = 0; fail: av_freep(&profiles); av_freep(&entrypoints); return err; }


static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStream* s, UINT16 flags)
{
	int i;
	BYTE iBitmapFormat;
	BOOL compressed = FALSE;
	CACHE_BRUSH_ORDER* cache_brush = calloc(1, sizeof(CACHE_BRUSH_ORDER));

	if (!cache_brush)
		goto fail;

	if (Stream_GetRemainingLength(s) < 6)
		goto fail;

	Stream_Read_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */
	Stream_Read_UINT8(s, iBitmapFormat);      /* iBitmapFormat (1 byte) */

	if (iBitmapFormat >= ARRAYSIZE(BMF_BPP))
		goto fail;

	cache_brush->bpp = BMF_BPP[iBitmapFormat];
	Stream_Read_UINT8(s, cache_brush->cx);     /* cx (1 byte) */
	Stream_Read_UINT8(s, cache_brush->cy);     /* cy (1 byte) */
	Stream_Read_UINT8(s, cache_brush->style);  /* style (1 byte) */
	Stream_Read_UINT8(s, cache_brush->length); /* iBytes (1 byte) */

	if ((cache_brush->cx == 8) && (cache_brush->cy == 8))
	{
		if (cache_brush->bpp == 1)
		{
			if (cache_brush->length != 8)
			{
				WLog_Print(update->log, WLOG_ERROR, "incompatible 1bpp brush of length:%" PRIu32 "",
				           cache_brush->length);
				goto fail;
			}

			/* rows are encoded in reverse order */
			if (Stream_GetRemainingLength(s) < 8)
				goto fail;

			for (i = 7; i >= 0; i--)
			{
				Stream_Read_UINT8(s, cache_brush->data[i]);
			}
		}
		else
		{
			if ((iBitmapFormat == BMF_8BPP) && (cache_brush->length == 20))
				compressed = TRUE;
			else if ((iBitmapFormat == BMF_16BPP) && (cache_brush->length == 24))
				compressed = TRUE;
			else if ((iBitmapFormat == BMF_32BPP) && (cache_brush->length == 32))
				compressed = TRUE;

			if (compressed != FALSE)
			{
				/* compressed brush */
				if (!update_decompress_brush(s, cache_brush->data, sizeof(cache_brush->data),
				                             cache_brush->bpp))
					goto fail;
			}
			else
			{
				/* uncompressed brush */
				UINT32 scanline = (cache_brush->bpp / 8) * 8;

				if (Stream_GetRemainingLength(s) < scanline * 8)
					goto fail;

				for (i = 7; i >= 0; i--)
				{
					Stream_Read(s, &cache_brush->data[i * scanline], scanline);
				}
			}
		}
	}

	return cache_brush;
fail:
	free_cache_brush_order(update->context, cache_brush);
	return NULL;
}


Encoding * PSSlurpEncodings ( FILE * file ) {
 char * names [ 1024 ] ;
 int32 encs [ 1024 ] ;
 Encoding * item , * head = NULL , * last ;
 char * encname ;
 char tokbuf [ 200 ] ;
 IO wrapper ;
 real dval ;
 size_t i , any ;
 int max , enc , codepointsonly , tok ;
 wrapper . top = NULL ;
 wrapper . advance_width = UNDEFINED_WIDTH ;
 pushio ( & wrapper , file , NULL , 0 ) ;
 while ( ( tok = nextpstoken ( & wrapper , & dval , tokbuf , sizeof ( tokbuf ) ) ) != pt_eof ) {
 encname = NULL ;
 if ( tok == pt_namelit ) {
 encname = copy ( tokbuf ) ;
 tok = nextpstoken ( & wrapper , & dval , tokbuf , sizeof ( tokbuf ) ) ;
 }
 if ( tok != pt_openarray && tok != pt_opencurly ) return ( head ) ;
 for ( i = 0 ;
 i < sizeof ( names ) / sizeof ( names [ 0 ] ) ;
 ++ i ) {
 encs [ i ] = - 1 ;
 names [ i ] = NULL ;
 }
 codepointsonly = CheckCodePointsComment ( & wrapper ) ;
 max = - 1 ;
 any = 0 ;
 for ( i = 0 ;
 ( tok = nextpstoken ( & wrapper , & dval , tokbuf , sizeof ( tokbuf ) ) ) != pt_eof && tok != pt_closearray && tok != pt_closecurly ;
 i ++ ) {
 if ( tok == pt_namelit && i < sizeof ( names ) / sizeof ( names [ 0 ] ) ) {
 max = i ;
 if ( strcmp ( tokbuf , ".notdef" ) == 0 ) {
 encs [ i ] = - 1 ;
 }
 else if ( ( enc = UniFromName ( tokbuf , ui_none , & custom ) ) != - 1 ) {
 encs [ i ] = enc ;
 names [ i ] = copy ( tokbuf ) ;
 any = 1 ;
 }
 else {
 names [ i ] = copy ( tokbuf ) ;
 any = 1 ;
 }
 }
 }
 if ( encname != NULL ) {
 tok = nextpstoken ( & wrapper , & dval , tokbuf , sizeof ( tokbuf ) ) ;
 if ( tok == pt_def ) {
 }
 else {
 }
 }
 if ( max != - 1 ) {
 if ( ++ max < 256 ) max = 256 ;
 item = calloc ( 1 , sizeof ( Encoding ) ) ;
 item -> enc_name = encname ;
 item -> char_cnt = max ;
 item -> unicode = malloc ( max * sizeof ( int32 ) ) ;
 memcpy ( item -> unicode , encs , max * sizeof ( int32 ) ) ;
 if ( any && ! codepointsonly ) {
 item -> psnames = calloc ( max , sizeof ( char * ) ) ;
 memcpy ( item -> psnames , names , max * sizeof ( char * ) ) ;
 }
 else {
 for ( i = 0 ;
 i < max ;
 ++ i ) free ( names [ i ] ) ;
 }
 if ( head == NULL ) head = item ;
 else last -> next = item ;
 last = item ;
 }
 }
 return ( head ) ;
 }


static void adb_kbd_realizefn(DeviceState *dev, Error **errp) { ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev); akc->parent_realize(dev, errp); qemu_input_handler_register(dev, &adb_keyboard_handler); }


static void StorePicturePTS ( encoder_t * p_enc , uint32_t u_pnum , mtime_t i_pts ) {
 encoder_sys_t * p_sys = p_enc -> p_sys ;
 for ( int i = 0 ;
 i < SCHRO_PTS_TLB_SIZE ;
 i ++ ) {
 if ( p_sys -> pts_tlb [ i ] . b_empty ) {
 p_sys -> pts_tlb [ i ] . u_pnum = u_pnum ;
 p_sys -> pts_tlb [ i ] . i_pts = i_pts ;
 p_sys -> pts_tlb [ i ] . b_empty = false ;
 return ;
 }
 }
 msg_Err ( p_enc , "Could not store PTS %" PRId64 " for frame %u" , i_pts , u_pnum ) ;
 }


static int ram_save_block(QEMUFile *f, bool last_stage) { RAMBlock *block = last_seen_block; ram_addr_t offset = last_offset; bool complete_round = false; int bytes_sent = 0; MemoryRegion *mr; ram_addr_t current_addr; if (!block) block = QTAILQ_FIRST(&ram_list.blocks); while (true) { mr = block->mr; offset = migration_bitmap_find_and_reset_dirty(mr, offset); if (complete_round && block == last_seen_block && offset >= last_offset) { break; } if (offset >= block->length) { offset = 0; block = QTAILQ_NEXT(block, next); if (!block) { block = QTAILQ_FIRST(&ram_list.blocks); complete_round = true; ram_bulk_stage = false; } } else { int ret; uint8_t *p; int cont = (block == last_sent_block) ? RAM_SAVE_FLAG_CONTINUE : 0; p = memory_region_get_ram_ptr(mr) + offset; /* In doubt sent page as normal */ bytes_sent = -1; ret = ram_control_save_page(f, block->offset, offset, TARGET_PAGE_SIZE, &bytes_sent); if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { if (ret != RAM_SAVE_CONTROL_DELAYED) { if (bytes_sent > 0) { acct_info.norm_pages++; } else if (bytes_sent == 0) { acct_info.dup_pages++; } } } else if (is_zero_range(p, TARGET_PAGE_SIZE)) { acct_info.dup_pages++; bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS); qemu_put_byte(f, 0); bytes_sent++; } else if (!ram_bulk_stage && migrate_use_xbzrle()) { current_addr = block->offset + offset; bytes_sent = save_xbzrle_page(f, p, current_addr, block, offset, cont, last_stage); if (!last_stage) { p = get_cached_data(XBZRLE.cache, current_addr); } } /* XBZRLE overflow or normal page */ if (bytes_sent == -1) { bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE); qemu_put_buffer_async(f, p, TARGET_PAGE_SIZE); bytes_sent += TARGET_PAGE_SIZE; acct_info.norm_pages++; } /* if page is unmodified, continue to the next */ if (bytes_sent > 0) { last_sent_block = block; break; } } } last_seen_block = block; last_offset = offset; return bytes_sent; }


static fz_font * xps_lookup_font ( xps_document * doc , char * name ) {
 xps_font_cache * cache ;
 for ( cache = doc -> font_table ;
 cache ;
 cache = cache -> next ) if ( ! xps_strcasecmp ( cache -> name , name ) ) return fz_keep_font ( doc -> ctx , cache -> font ) ;
 return NULL ;
 }


static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags)
{
	BOOL rc = FALSE;
	size_t start, end, diff;
	BYTE orderType;
	UINT16 extraFlags;
	UINT16 orderLength;
	rdpContext* context = update->context;
	rdpSettings* settings = context->settings;
	rdpSecondaryUpdate* secondary = update->secondary;
	const char* name;

	if (Stream_GetRemainingLength(s) < 5)
	{
		WLog_Print(update->log, WLOG_ERROR, "Stream_GetRemainingLength(s) < 5");
		return FALSE;
	}

	Stream_Read_UINT16(s, orderLength); /* orderLength (2 bytes) */
	Stream_Read_UINT16(s, extraFlags);  /* extraFlags (2 bytes) */
	Stream_Read_UINT8(s, orderType);    /* orderType (1 byte) */
	if (Stream_GetRemainingLength(s) < orderLength + 7U)
	{
		WLog_Print(update->log, WLOG_ERROR, "Stream_GetRemainingLength(s) %" PRIuz " < %" PRIu16,
		           Stream_GetRemainingLength(s), orderLength + 7);
		return FALSE;
	}

	start = Stream_GetPosition(s);
	name = secondary_order_string(orderType);
	WLog_Print(update->log, WLOG_DEBUG, "Secondary Drawing Order %s", name);

	if (!check_secondary_order_supported(update->log, settings, orderType, name))
		return FALSE;

	switch (orderType)
	{
		case ORDER_TYPE_BITMAP_UNCOMPRESSED:
		case ORDER_TYPE_CACHE_BITMAP_COMPRESSED:
		{
			const BOOL compressed = (orderType == ORDER_TYPE_CACHE_BITMAP_COMPRESSED);
			CACHE_BITMAP_ORDER* order =
			    update_read_cache_bitmap_order(update, s, compressed, extraFlags);

			if (order)
			{
				rc = IFCALLRESULT(FALSE, secondary->CacheBitmap, context, order);
				free_cache_bitmap_order(context, order);
			}
		}
		break;

		case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2:
		case ORDER_TYPE_BITMAP_COMPRESSED_V2:
		{
			const BOOL compressed = (orderType == ORDER_TYPE_BITMAP_COMPRESSED_V2);
			CACHE_BITMAP_V2_ORDER* order =
			    update_read_cache_bitmap_v2_order(update, s, compressed, extraFlags);

			if (order)
			{
				rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV2, context, order);
				free_cache_bitmap_v2_order(context, order);
			}
		}
		break;

		case ORDER_TYPE_BITMAP_COMPRESSED_V3:
		{
			CACHE_BITMAP_V3_ORDER* order = update_read_cache_bitmap_v3_order(update, s, extraFlags);

			if (order)
			{
				rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV3, context, order);
				free_cache_bitmap_v3_order(context, order);
			}
		}
		break;

		case ORDER_TYPE_CACHE_COLOR_TABLE:
		{
			CACHE_COLOR_TABLE_ORDER* order =
			    update_read_cache_color_table_order(update, s, extraFlags);

			if (order)
			{
				rc = IFCALLRESULT(FALSE, secondary->CacheColorTable, context, order);
				free_cache_color_table_order(context, order);
			}
		}
		break;

		case ORDER_TYPE_CACHE_GLYPH:
		{
			switch (settings->GlyphSupportLevel)
			{
				case GLYPH_SUPPORT_PARTIAL:
				case GLYPH_SUPPORT_FULL:
				{
					CACHE_GLYPH_ORDER* order = update_read_cache_glyph_order(update, s, extraFlags);

					if (order)
					{
						rc = IFCALLRESULT(FALSE, secondary->CacheGlyph, context, order);
						free_cache_glyph_order(context, order);
					}
				}
				break;

				case GLYPH_SUPPORT_ENCODE:
				{
					CACHE_GLYPH_V2_ORDER* order =
					    update_read_cache_glyph_v2_order(update, s, extraFlags);

					if (order)
					{
						rc = IFCALLRESULT(FALSE, secondary->CacheGlyphV2, context, order);
						free_cache_glyph_v2_order(context, order);
					}
				}
				break;

				case GLYPH_SUPPORT_NONE:
				default:
					break;
			}
		}
		break;

		case ORDER_TYPE_CACHE_BRUSH:
			/* [MS-RDPEGDI] 2.2.2.2.1.2.7 Cache Brush (CACHE_BRUSH_ORDER) */
			{
				CACHE_BRUSH_ORDER* order = update_read_cache_brush_order(update, s, extraFlags);

				if (order)
				{
					rc = IFCALLRESULT(FALSE, secondary->CacheBrush, context, order);
					free_cache_brush_order(context, order);
				}
			}
			break;

		default:
			WLog_Print(update->log, WLOG_WARN, "SECONDARY ORDER %s not supported", name);
			break;
	}

	if (!rc)
	{
		WLog_Print(update->log, WLOG_ERROR, "SECONDARY ORDER %s failed", name);
	}

	start += orderLength + 7;
	end = Stream_GetPosition(s);
	if (start > end)
	{
		WLog_Print(update->log, WLOG_WARN, "SECONDARY_ORDER %s: read %" PRIuz "bytes too much",
		           name, end - start);
		return FALSE;
	}
	diff = start - end;
	if (diff > 0)
	{
		WLog_Print(update->log, WLOG_DEBUG,
		           "SECONDARY_ORDER %s: read %" PRIuz "bytes short, skipping", name, diff);
		Stream_Seek(s, diff);
	}
	return rc;
}


void do_info_vnc(void) { if (vnc_state == NULL) term_printf("VNC server disabled\n"); else { term_printf("VNC server active on: "); term_print_filename(vnc_state->display); term_printf("\n"); if (vnc_state->csock == -1) term_printf("No client connected\n"); else term_printf("Client connected\n"); } }


static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
{
}


int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) { int f_code; if(s->me_method>=ME_EPZS){ int mv_num[8]; int i, y; int loose=0; UINT8 * fcode_tab= s->fcode_tab; for(i=0; i<8; i++) mv_num[i]=0; for(y=0; y<s->mb_height; y++){ int x; int xy= (y+1)* (s->mb_width+2) + 1; i= y*s->mb_width; for(x=0; x<s->mb_width; x++){ if(s->mb_type[i] & type){ mv_num[ fcode_tab[mv_table[xy][0] + MAX_MV] ]++; mv_num[ fcode_tab[mv_table[xy][1] + MAX_MV] ]++; //printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i); } i++; xy++; } } for(i=MAX_FCODE; i>1; i--){ int threshold; loose+= mv_num[i]; if(s->pict_type==B_TYPE) threshold= 0; else threshold= s->mb_num/20; //FIXME if(loose > threshold) break; } // printf("fcode: %d type: %d\n", i, s->pict_type); return i; /* for(i=0; i<=MAX_FCODE; i++){ printf("%d ", mv_num[i]); } printf("\n");*/ }else{ return 1; } }


__mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
{
	struct timer_base *base, *new_base;
	unsigned int idx = UINT_MAX;
	unsigned long clk = 0, flags;
	int ret = 0;

	BUG_ON(!timer->function);

	/*
	 * This is a common optimization triggered by the networking code - if
	 * the timer is re-modified to have the same timeout or ends up in the
	 * same array bucket then just return:
	 */
	if (timer_pending(timer)) {
		if (timer->expires == expires)
			return 1;

		/*
		 * We lock timer base and calculate the bucket index right
		 * here. If the timer ends up in the same bucket, then we
		 * just update the expiry time and avoid the whole
		 * dequeue/enqueue dance.
		 */
		base = lock_timer_base(timer, &flags);

		clk = base->clk;
		idx = calc_wheel_index(expires, clk);

		/*
		 * Retrieve and compare the array index of the pending
		 * timer. If it matches set the expiry to the new value so a
		 * subsequent call will exit in the expires check above.
		 */
		if (idx == timer_get_idx(timer)) {
			timer->expires = expires;
			ret = 1;
			goto out_unlock;
		}
	} else {
		base = lock_timer_base(timer, &flags);
	}

	timer_stats_timer_set_start_info(timer);

	ret = detach_if_pending(timer, base, false);
	if (!ret && pending_only)
		goto out_unlock;

	debug_activate(timer, expires);

	new_base = get_target_base(base, timer->flags);

	if (base != new_base) {
		/*
		 * We are trying to schedule the timer on the new base.
		 * However we can't change timer's base while it is running,
		 * otherwise del_timer_sync() can't detect that the timer's
		 * handler yet has not finished. This also guarantees that the
		 * timer is serialized wrt itself.
		 */
		if (likely(base->running_timer != timer)) {
			/* See the comment in lock_timer_base() */
			timer->flags |= TIMER_MIGRATING;

			spin_unlock(&base->lock);
			base = new_base;
			spin_lock(&base->lock);
			WRITE_ONCE(timer->flags,
				   (timer->flags & ~TIMER_BASEMASK) | base->cpu);
		}
	}

	/* Try to forward a stale timer base clock */
	forward_timer_base(base);

	timer->expires = expires;
	/*
	 * If 'idx' was calculated above and the base time did not advance
	 * between calculating 'idx' and possibly switching the base, only
	 * enqueue_timer() and trigger_dyntick_cpu() is required. Otherwise
	 * we need to (re)calculate the wheel index via
	 * internal_add_timer().
	 */
	if (idx != UINT_MAX && clk == base->clk) {
		enqueue_timer(base, timer, idx);
		trigger_dyntick_cpu(base, timer);
	} else {
		internal_add_timer(base, timer);
	}

out_unlock:
	spin_unlock_irqrestore(&base->lock, flags);

	return ret;
}


void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr)
{
	if (timer->start_site)
		return;

	timer->start_site = addr;
	memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
	timer->start_pid = current->pid;
}


static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, AVCodecContext *dec_ctx) { AVPacket enc_pkt; AVFrame *in_frame, *out_frame; uint8_t *raw_in = NULL, *raw_out = NULL; int in_offset = 0, out_offset = 0; int frame_data_size = 0; int result = 0; int got_output = 0; int i = 0; in_frame = av_frame_alloc(); if (!in_frame) { av_log(NULL, AV_LOG_ERROR, "Can't allocate input frame\n"); return AVERROR(ENOMEM); } in_frame->nb_samples = enc_ctx->frame_size; in_frame->format = enc_ctx->sample_fmt; in_frame->channel_layout = enc_ctx->channel_layout; if (av_frame_get_buffer(in_frame, 32) != 0) { av_log(NULL, AV_LOG_ERROR, "Can't allocate a buffer for input frame\n"); return AVERROR(ENOMEM); } out_frame = av_frame_alloc(); if (!out_frame) { av_log(NULL, AV_LOG_ERROR, "Can't allocate output frame\n"); return AVERROR(ENOMEM); } raw_in = av_malloc(in_frame->linesize[0] * NUMBER_OF_FRAMES); if (!raw_in) { av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for raw_in\n"); return AVERROR(ENOMEM); } raw_out = av_malloc(in_frame->linesize[0] * NUMBER_OF_FRAMES); if (!raw_out) { av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for raw_out\n"); return AVERROR(ENOMEM); } for (i = 0; i < NUMBER_OF_FRAMES; i++) { av_init_packet(&enc_pkt); enc_pkt.data = NULL; enc_pkt.size = 0; generate_raw_frame((uint16_t*)(in_frame->data[0]), i, enc_ctx->sample_rate, enc_ctx->channels, enc_ctx->frame_size); memcpy(raw_in + in_offset, in_frame->data[0], in_frame->linesize[0]); in_offset += in_frame->linesize[0]; result = avcodec_encode_audio2(enc_ctx, &enc_pkt, in_frame, &got_output); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error encoding audio frame\n"); return result; } /* if we get an encoded packet, feed it straight to the decoder */ if (got_output) { result = avcodec_decode_audio4(dec_ctx, out_frame, &got_output, &enc_pkt); if (result < 0) { av_log(NULL, AV_LOG_ERROR, "Error decoding audio packet\n"); return result; } if (got_output) { if (result != enc_pkt.size) { av_log(NULL, AV_LOG_INFO, "Decoder consumed only part of a packet, it is allowed to do so -- need to update this test\n"); return AVERROR_UNKNOWN; } if (in_frame->nb_samples != out_frame->nb_samples) { av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different number of samples\n"); return AVERROR_UNKNOWN; } if (in_frame->channel_layout != out_frame->channel_layout) { av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different channel layout\n"); return AVERROR_UNKNOWN; } if (in_frame->format != out_frame->format) { av_log(NULL, AV_LOG_ERROR, "Error frames before and after decoding has different sample format\n"); return AVERROR_UNKNOWN; } memcpy(raw_out + out_offset, out_frame->data[0], out_frame->linesize[0]); out_offset += out_frame->linesize[0]; } } av_free_packet(&enc_pkt); } if (memcmp(raw_in, raw_out, frame_data_size * NUMBER_OF_FRAMES) != 0) { av_log(NULL, AV_LOG_ERROR, "Output differs\n"); return 1; } av_log(NULL, AV_LOG_INFO, "OK\n"); av_freep(&raw_in); av_freep(&raw_out); av_frame_free(&in_frame); av_frame_free(&out_frame); return 0; }


static av_cold int pcm_encode_init(AVCodecContext *avctx) { avctx->frame_size = 0; switch(avctx->codec->id) { case CODEC_ID_PCM_ALAW: pcm_alaw_tableinit(); break; case CODEC_ID_PCM_MULAW: pcm_ulaw_tableinit(); break; default: break; } avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample/8; avctx->coded_frame= avcodec_alloc_frame(); return 0; }


static ENUM_PTRS_WITH ( gx_ttfReader_enum_ptrs , gx_ttfReader * mptr ) {
 DISCARD ( mptr ) ;
 return 0 ;
 }


static int tight_fill_palette(VncState *vs, int x, int y,
                              size_t count, uint32_t *bg, uint32_t *fg,
                              VncPalette **palette)
{
    int max;

    max = count / tight_conf[vs->tight.compression].idx_max_colors_divisor;
    if (max < 2 &&
        count >= tight_conf[vs->tight.compression].mono_min_rect_size) {
        max = 2;
    }
    if (max >= 256) {
        max = 256;
    }

    switch(vs->clientds.pf.bytes_per_pixel) {
    case 4:
        return tight_fill_palette32(vs, x, y, max, count, bg, fg, palette);
    case 2:
        return tight_fill_palette16(vs, x, y, max, count, bg, fg, palette);
    default:
        max = 2;
        return tight_fill_palette8(vs, x, y, max, count, bg, fg, palette);
    }
    return 0;
}


static void add_pc_test_cases(void) { QDict *response, *minfo; QList *list; const QListEntry *p; QObject *qobj; QString *qstr; const char *mname, *path; PCTestData *data; qtest_start("-machine none"); response = qmp("{ 'execute': 'query-machines' }"); g_assert(response); list = qdict_get_qlist(response, "return"); g_assert(list); for (p = qlist_first(list); p; p = qlist_next(p)) { minfo = qobject_to_qdict(qlist_entry_obj(p)); g_assert(minfo); qobj = qdict_get(minfo, "name"); g_assert(qobj); qstr = qobject_to_qstring(qobj); g_assert(qstr); mname = qstring_get_str(qstr); if (!g_str_has_prefix(mname, "pc-")) { continue; } data = g_malloc(sizeof(PCTestData)); data->machine = mname; data->cpu_model = "Haswell"; /* 1.3+ theoretically */ data->sockets = 1; data->cores = 3; data->threads = 2; data->maxcpus = data->sockets * data->cores * data->threads * 2; if (g_str_has_suffix(mname, "-1.4") || (strcmp(mname, "pc-1.3") == 0) || (strcmp(mname, "pc-1.2") == 0) || (strcmp(mname, "pc-1.1") == 0) || (strcmp(mname, "pc-1.0") == 0) || (strcmp(mname, "pc-0.15") == 0) || (strcmp(mname, "pc-0.14") == 0) || (strcmp(mname, "pc-0.13") == 0) || (strcmp(mname, "pc-0.12") == 0) || (strcmp(mname, "pc-0.11") == 0) || (strcmp(mname, "pc-0.10") == 0)) { path = g_strdup_printf("cpu/%s/init/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_without_cpu_add); } else { path = g_strdup_printf("cpu/%s/add/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_with_cpu_add); } } qtest_end(); }


static char * unescape_word ( struct Curl_easy * data , const char * inputbuff ) {
 char * newp ;
 char * dictp ;
 char * ptr ;
 size_t len ;
 char ch ;
 int olen = 0 ;
 CURLcode result = Curl_urldecode ( data , inputbuff , 0 , & newp , & len , FALSE ) ;
 if ( ! newp || result ) return NULL ;
 dictp = malloc ( ( ( size_t ) len ) * 2 + 1 ) ;
 if ( dictp ) {
 for ( ptr = newp ;
 ( ch = * ptr ) != 0 ;
 ptr ++ ) {
 if ( ( ch <= 32 ) || ( ch == 127 ) || ( ch == '\'' ) || ( ch == '\"' ) || ( ch == '\\' ) ) {
 dictp [ olen ++ ] = '\\' ;
 }
 dictp [ olen ++ ] = ch ;
 }
 dictp [ olen ] = 0 ;
 }
 free ( newp ) ;
 return dictp ;
 }


BOOL nsc_process_message(NSC_CONTEXT* context, UINT16 bpp,
                         UINT32 width, UINT32 height,
                         const BYTE* data, UINT32 length,
                         BYTE* pDstData, UINT32 DstFormat,
                         UINT32 nDstStride,
                         UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
                         UINT32 nHeight, UINT32 flip)
{
	wStream* s;
	BOOL ret;
	s = Stream_New((BYTE*)data, length);

	if (!s)
		return FALSE;

	if (nDstStride == 0)
		nDstStride = nWidth * GetBytesPerPixel(DstFormat);

	switch (bpp)
	{
		case 32:
			context->format = PIXEL_FORMAT_BGRA32;
			break;

		case 24:
			context->format = PIXEL_FORMAT_BGR24;
			break;

		case 16:
			context->format = PIXEL_FORMAT_BGR16;
			break;

		case 8:
			context->format = PIXEL_FORMAT_RGB8;
			break;

		case 4:
			context->format = PIXEL_FORMAT_A4;
			break;

		default:
			Stream_Free(s, TRUE);
			return FALSE;
	}

	context->width = width;
	context->height = height;
	ret = nsc_context_initialize(context, s);
	Stream_Free(s, FALSE);

	if (!ret)
		return FALSE;

	/* RLE decode */
	PROFILER_ENTER(context->priv->prof_nsc_rle_decompress_data)
	nsc_rle_decompress_data(context);
	PROFILER_EXIT(context->priv->prof_nsc_rle_decompress_data)
	/* Colorloss recover, Chroma supersample and AYCoCg to ARGB Conversion in one step */
	PROFILER_ENTER(context->priv->prof_nsc_decode)
	context->decode(context);
	PROFILER_EXIT(context->priv->prof_nsc_decode)

	if (!freerdp_image_copy(pDstData, DstFormat, nDstStride, nXDst, nYDst,
	                        width, height, context->BitmapData,
	                        PIXEL_FORMAT_BGRA32, 0, 0, 0, NULL, flip))
		return FALSE;

	return TRUE;
}


BOOL nsc_process_message(NSC_CONTEXT* context, UINT16 bpp,
                         UINT32 width, UINT32 height,
                         const BYTE* data, UINT32 length,
                         BYTE* pDstData, UINT32 DstFormat,
                         UINT32 nDstStride,
                         UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
                         UINT32 nHeight, UINT32 flip)
{
	wStream* s;
	BOOL ret;
	s = Stream_New((BYTE*)data, length);

	if (!s)
		return FALSE;

	if (nDstStride == 0)
		nDstStride = nWidth * GetBytesPerPixel(DstFormat);

	switch (bpp)
	{
		case 32:
			context->format = PIXEL_FORMAT_BGRA32;
			break;

		case 24:
			context->format = PIXEL_FORMAT_BGR24;
			break;

		case 16:
			context->format = PIXEL_FORMAT_BGR16;
			break;

		case 8:
			context->format = PIXEL_FORMAT_RGB8;
			break;

		case 4:
			context->format = PIXEL_FORMAT_A4;
			break;

		default:
			Stream_Free(s, TRUE);
			return FALSE;
	}

	context->width = width;
	context->height = height;
	ret = nsc_context_initialize(context, s);
	Stream_Free(s, FALSE);

	if (!ret)
		return FALSE;

	/* RLE decode */
	{
		BOOL rc;
		PROFILER_ENTER(context->priv->prof_nsc_rle_decompress_data)
		rc = nsc_rle_decompress_data(context);
		PROFILER_EXIT(context->priv->prof_nsc_rle_decompress_data)

		if (!rc)
			return FALSE;
	}
	/* Colorloss recover, Chroma supersample and AYCoCg to ARGB Conversion in one step */
	{
		BOOL rc;
		PROFILER_ENTER(context->priv->prof_nsc_decode)
		rc = context->decode(context);
		PROFILER_EXIT(context->priv->prof_nsc_decode)

		if (!rc)
			return FALSE;
	}

	if (!freerdp_image_copy(pDstData, DstFormat, nDstStride, nXDst, nYDst,
	                        width, height, context->BitmapData,
	                        PIXEL_FORMAT_BGRA32, 0, 0, 0, NULL, flip))
		return FALSE;

	return TRUE;
}


BOOL nsc_encode(NSC_CONTEXT* context, const BYTE* bmpdata, UINT32 rowstride)
{
	if (!context || !bmpdata || (rowstride == 0))
		return FALSE;

	if (!nsc_encode_argb_to_aycocg(context, bmpdata, rowstride))
		return FALSE;

	if (context->ChromaSubsamplingLevel)
	{
		if (!nsc_encode_subsampling(context))
			return FALSE;
	}

	return TRUE;
}


static void pfkey_insert ( struct sock * sk ) {
 struct net * net = sock_net ( sk ) ;
 struct netns_pfkey * net_pfkey = net_generic ( net , pfkey_net_id ) ;
 mutex_lock ( & pfkey_mutex ) ;
 sk_add_node_rcu ( sk , & net_pfkey -> table ) ;
 mutex_unlock ( & pfkey_mutex ) ;
 }


static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
                             uint32_t* color, bool samecolor)
{
    VncDisplay *vd = vs->vd;

    switch(vd->server->pf.bytes_per_pixel) {
    case 4:
        return check_solid_tile32(vs, x, y, w, h, color, samecolor);
    case 2:
        return check_solid_tile16(vs, x, y, w, h, color, samecolor);
    default:
        return check_solid_tile8(vs, x, y, w, h, color, samecolor);
    }
}


int ff_h264_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { H264Context *h = dst->priv_data, *h1 = src->priv_data; int inited = h->context_initialized, err = 0; int need_reinit = 0; int i, ret; if (dst == src || !h1->context_initialized) return 0; if (!h1->ps.sps) return AVERROR_INVALIDDATA; if (inited && (h->width != h1->width || h->height != h1->height || h->mb_width != h1->mb_width || h->mb_height != h1->mb_height || !h->ps.sps || h->ps.sps->bit_depth_luma != h1->ps.sps->bit_depth_luma || h->ps.sps->chroma_format_idc != h1->ps.sps->chroma_format_idc || h->ps.sps->colorspace != h1->ps.sps->colorspace)) { need_reinit = 1; } // SPS/PPS for (i = 0; i < FF_ARRAY_ELEMS(h->ps.sps_list); i++) { av_buffer_unref(&h->ps.sps_list[i]); if (h1->ps.sps_list[i]) { h->ps.sps_list[i] = av_buffer_ref(h1->ps.sps_list[i]); if (!h->ps.sps_list[i]) return AVERROR(ENOMEM); } } for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++) { av_buffer_unref(&h->ps.pps_list[i]); if (h1->ps.pps_list[i]) { h->ps.pps_list[i] = av_buffer_ref(h1->ps.pps_list[i]); if (!h->ps.pps_list[i]) return AVERROR(ENOMEM); } } h->ps.sps = h1->ps.sps; if (need_reinit || !inited) { h->width = h1->width; h->height = h1->height; h->mb_height = h1->mb_height; h->mb_width = h1->mb_width; h->mb_num = h1->mb_num; h->mb_stride = h1->mb_stride; h->b_stride = h1->b_stride; if ((err = h264_slice_header_init(h)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed"); return err; } /* copy block_offset since frame_start may not be called */ memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset)); } h->avctx->coded_height = h1->avctx->coded_height; h->avctx->coded_width = h1->avctx->coded_width; h->avctx->width = h1->avctx->width; h->avctx->height = h1->avctx->height; h->coded_picture_number = h1->coded_picture_number; h->first_field = h1->first_field; h->picture_structure = h1->picture_structure; h->droppable = h1->droppable; h->low_delay = h1->low_delay; for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) { ff_h264_unref_picture(h, &h->DPB[i]); if (h1->DPB[i].f->buf[0] && (ret = ff_h264_ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0) return ret; } h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1); ff_h264_unref_picture(h, &h->cur_pic); if (h1->cur_pic.f->buf[0]) { ret = ff_h264_ref_picture(h, &h->cur_pic, &h1->cur_pic); if (ret < 0) return ret; } h->enable_er = h1->enable_er; h->workaround_bugs = h1->workaround_bugs; h->low_delay = h1->low_delay; h->droppable = h1->droppable; // extradata/NAL handling h->is_avc = h1->is_avc; h->nal_length_size = h1->nal_length_size; // POC timing copy_fields(h, h1, poc_lsb, current_slice); copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1); copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1); copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT + 2, h, h1); if (!h->cur_pic_ptr) return 0; if (!h->droppable) { err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); h->prev_poc_msb = h->poc_msb; h->prev_poc_lsb = h->poc_lsb; } h->prev_frame_num_offset = h->frame_num_offset; h->prev_frame_num = h->frame_num; h->recovery_frame = h1->recovery_frame; h->frame_recovered = h1->frame_recovered; return err; }


static BOOL nsc_encode_sse2(NSC_CONTEXT* context, const BYTE* data,
                            UINT32 scanline)
{
	nsc_encode_argb_to_aycocg_sse2(context, data, scanline);

	if (context->ChromaSubsamplingLevel > 0)
	{
		nsc_encode_subsampling_sse2(context);
	}

	return TRUE;
}


static void vnc_write_pixels_generic(VncState *vs, struct PixelFormat *pf,
                                     void *pixels1, int size)
{
    uint8_t buf[4];

    if (pf->bytes_per_pixel == 4) {
        uint32_t *pixels = pixels1;
        int n, i;
        n = size >> 2;
        for(i = 0; i < n; i++) {
            vnc_convert_pixel(vs, buf, pixels[i]);
            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        }
    } else if (pf->bytes_per_pixel == 2) {
        uint16_t *pixels = pixels1;
        int n, i;
        n = size >> 1;
        for(i = 0; i < n; i++) {
            vnc_convert_pixel(vs, buf, pixels[i]);
            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        }
    } else if (pf->bytes_per_pixel == 1) {
        uint8_t *pixels = pixels1;
        int n, i;
        n = size;
        for(i = 0; i < n; i++) {
            vnc_convert_pixel(vs, buf, pixels[i]);
            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
        }
    } else {
        fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
    }
}


static inline void copy_backptr(LZOContext *c, int back, int cnt) { register const uint8_t *src = &c->out[-back]; register uint8_t *dst = c->out; if (src < c->out_start || src > dst) { c->error |= AV_LZO_INVALID_BACKPTR; return; } if (cnt > c->out_end - dst) { cnt = FFMAX(c->out_end - dst, 0); c->error |= AV_LZO_OUTPUT_FULL; } av_memcpy_backptr(dst, back, cnt); c->out = dst + cnt; }


static int vnc_update_stats(VncDisplay *vd,  struct timeval * tv)
{
    int x, y;
    struct timeval res;
    int has_dirty = 0;

    for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
        for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
            VncRectStat *rect = vnc_stat_rect(vd, x, y);

            rect->updated = false;
        }
    }

    qemu_timersub(tv, &VNC_REFRESH_STATS, &res);

    if (timercmp(&vd->guest.last_freq_check, &res, >)) {
        return has_dirty;
    }
    vd->guest.last_freq_check = *tv;

    for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
        for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
            VncRectStat *rect= vnc_stat_rect(vd, x, y);
            int count = ARRAY_SIZE(rect->times);
            struct timeval min, max;

            if (!timerisset(&rect->times[count - 1])) {
                continue ;
            }

            max = rect->times[(rect->idx + count - 1) % count];
            qemu_timersub(tv, &max, &res);

            if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
                rect->freq = 0;
                has_dirty += vnc_refresh_lossy_rect(vd, x, y);
                memset(rect->times, 0, sizeof (rect->times));
                continue ;
            }

            min = rect->times[rect->idx];
            max = rect->times[(rect->idx + count - 1) % count];
            qemu_timersub(&max, &min, &res);

            rect->freq = res.tv_sec + res.tv_usec / 1000000.;
            rect->freq /= count;
            rect->freq = 1. / rect->freq;
        }
    }
    return has_dirty;
}


static void kvm_s390_stattrib_synchronize(S390StAttribState *sa) { KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa); MachineState *machine = MACHINE(qdev_get_machine()); unsigned long max = machine->maxram_size / TARGET_PAGE_SIZE; unsigned long cx, len = 1 << 19; int r; struct kvm_s390_cmma_log clog = { .flags = 0, .mask = ~0ULL, }; if (sas->incoming_buffer) { for (cx = 0; cx + len <= max; cx += len) { clog.start_gfn = cx; clog.count = len; clog.values = (uint64_t)(sas->incoming_buffer + cx * len); r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); if (r) { error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); return; } } if (cx < max) { clog.start_gfn = cx; clog.count = max - cx; clog.values = (uint64_t)(sas->incoming_buffer + cx * len); r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); if (r) { error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); } } g_free(sas->incoming_buffer); sas->incoming_buffer = NULL; } }


static int am_handle_logout_request(request_rec *r,
                                    LassoLogout *logout, char *msg)
{
    gint res = 0, rc = HTTP_OK;
    am_cache_entry_t *session = NULL;
    am_dir_cfg_rec *cfg = am_get_dir_cfg(r);

    /* Process the logout message. Ignore missing signature. */
    res = lasso_logout_process_request_msg(logout, msg);
#ifdef HAVE_lasso_profile_set_signature_verify_hint
    if(res != 0 && res != LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
        if (apr_hash_get(cfg->do_not_verify_logout_signature,
                         logout->parent.remote_providerID,
                         APR_HASH_KEY_STRING)) {
            lasso_profile_set_signature_verify_hint(&logout->parent,
                LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE);
            res = lasso_logout_process_request_msg(logout, msg);
        }
    }
#endif
    if(res != 0 && res != LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "Error processing logout request message."
                      " Lasso error: [%i] %s", res, lasso_strerror(res));

        rc = HTTP_BAD_REQUEST;
        goto exit;
    }

    /* Search session using NameID */
    if (! LASSO_IS_SAML2_NAME_ID(logout->parent.nameIdentifier)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "Error processing logout request message."
                      " No NameID found");
        rc = HTTP_BAD_REQUEST;
        goto exit;
    }
    session = am_get_request_session_by_nameid(r,
                    ((LassoSaml2NameID*)logout->parent.nameIdentifier)->content);
    if (session == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "Error processing logout request message."
                      " No session found for NameID %s",
                      ((LassoSaml2NameID*)logout->parent.nameIdentifier)->content);

    }
    if (session == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "Error processing logout request message."
                      " No session found.");

    } else {
        am_restore_lasso_profile_state(r, &logout->parent, session);
    }

    /* Validate the logout message. Ignore missing signature. */
    res = lasso_logout_validate_request(logout);
    if(res != 0 &&
       res != LASSO_DS_ERROR_SIGNATURE_NOT_FOUND &&
       res != LASSO_PROFILE_ERROR_SESSION_NOT_FOUND) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "Error validating logout request."
                      " Lasso error: [%i] %s", res, lasso_strerror(res));
        rc = HTTP_INTERNAL_SERVER_ERROR;
        goto exit;
    }
    /* We continue with the logout despite those errors. They could be
     * caused by the IdP believing that we are logged in when we are not.
     */

    if (session != NULL && res != LASSO_PROFILE_ERROR_SESSION_NOT_FOUND) {
        /* We found a matching session -- delete it. */
        am_delete_request_session(r, session);
        session = NULL;
    }

    /* Create response message. */
    res = lasso_logout_build_response_msg(logout);
    if(res != 0) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "Error building logout response message."
                      " Lasso error: [%i] %s", res, lasso_strerror(res));

        rc = HTTP_INTERNAL_SERVER_ERROR;
        goto exit;
    }
    rc = am_return_logout_response(r, &logout->parent);

exit:
    if (session != NULL) {
        am_release_request_session(r, session);
    }

    lasso_logout_destroy(logout);
    return rc;
}


void hw_error ( const char * fmt , ... ) {
 va_list ap ;
 CPUArchState * env ;
 CPUState * cpu ;
 va_start ( ap , fmt ) ;
 fprintf ( stderr , "qemu: hardware error: " ) ;
 vfprintf ( stderr , fmt , ap ) ;
 fprintf ( stderr , "\n" ) ;
 for ( env = first_cpu ;
 env != NULL ;
 env = env -> next_cpu ) {
 cpu = ENV_GET_CPU ( env ) ;
 fprintf ( stderr , "CPU #%d:\n" , cpu -> cpu_index ) ;
 cpu_dump_state ( cpu , stderr , fprintf , CPU_DUMP_FPU ) ;
 }
 va_end ( ap ) ;
 abort ( ) ;
 }


static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t len) { uint32_t datalen = len; const char *serverout; unsigned int serveroutlen; int err; char *clientdata = NULL; /* NB, distinction of NULL vs "" is *critical* in SASL */ if (datalen) { clientdata = (char*)data; clientdata[datalen-1] = '\0'; /* Wire includes '\0', but make sure */ datalen--; /* Don't count NULL byte when passing to _start() */ } VNC_DEBUG("Step using SASL Data %p (%d bytes)\n", clientdata, datalen); err = sasl_server_step(vs->sasl.conn, clientdata, datalen, &serverout, &serveroutlen); if (err != SASL_OK && err != SASL_CONTINUE) { VNC_DEBUG("sasl step failed %d (%s)\n", err, sasl_errdetail(vs->sasl.conn)); sasl_dispose(&vs->sasl.conn); vs->sasl.conn = NULL; goto authabort; } if (serveroutlen > SASL_DATA_MAX_LEN) { VNC_DEBUG("sasl step reply data too long %d\n", serveroutlen); sasl_dispose(&vs->sasl.conn); vs->sasl.conn = NULL; goto authabort; } VNC_DEBUG("SASL return data %d bytes, nil; %d\n", serveroutlen, serverout ? 0 : 1); if (serveroutlen) { vnc_write_u32(vs, serveroutlen + 1); vnc_write(vs, serverout, serveroutlen + 1); } else { vnc_write_u32(vs, 0); } /* Whether auth is complete */ vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1); if (err == SASL_CONTINUE) { VNC_DEBUG("%s", "Authentication must continue\n"); /* Wait for step length */ vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4); } else { if (!vnc_auth_sasl_check_ssf(vs)) { VNC_DEBUG("Authentication rejected for weak SSF %p\n", vs->ioc); goto authreject; } /* Check username whitelist ACL */ if (vnc_auth_sasl_check_access(vs) < 0) { VNC_DEBUG("Authentication rejected for ACL %p\n", vs->ioc); goto authreject; } VNC_DEBUG("Authentication successful %p\n", vs->ioc); vnc_write_u32(vs, 0); /* Accept auth */ /* * Delay writing in SSF encoded mode until pending output * buffer is written */ if (vs->sasl.runSSF) vs->sasl.waitWriteSSF = vs->output.offset; start_client_init(vs); } return 0; authreject: vnc_write_u32(vs, 1); /* Reject auth */ vnc_write_u32(vs, sizeof("Authentication failed")); vnc_write(vs, "Authentication failed", sizeof("Authentication failed")); vnc_flush(vs); vnc_client_error(vs); return -1; authabort: vnc_client_error(vs); return -1; }


unsigned int srtp_get_version ( ) {
 unsigned int major = 0 , minor = 0 , micro = 0 ;
 unsigned int rv = 0 ;
 int parse_rv ;
 parse_rv = sscanf ( SRTP_VERSION , "%u.%u.%u" , & major , & minor , & micro ) ;
 if ( parse_rv != 3 ) {
 return ( 0 ) ;
 }
 rv |= ( major & 0xFF ) << 24 ;
 rv |= ( minor & 0xFF ) << 16 ;
 rv |= micro & 0xFF ;
 return rv ;
 }


void proto_reg_handoff_zbee_zcl_part ( void ) {
 dissector_handle_t part_handle ;
 part_handle = find_dissector ( ZBEE_PROTOABBREV_ZCL_PART ) ;
 dissector_add_uint ( "zbee.zcl.cluster" , ZBEE_ZCL_CID_PARTITION , part_handle ) ;
 zbee_zcl_init_cluster ( proto_zbee_zcl_part , ett_zbee_zcl_part , ZBEE_ZCL_CID_PARTITION , hf_zbee_zcl_part_attr_id , hf_zbee_zcl_part_srv_rx_cmd_id , hf_zbee_zcl_part_srv_tx_cmd_id , NULL ) ;
 }


static void generate_json_null ( FBuffer * buffer , VALUE Vstate , JSON_Generator_State * state , VALUE obj ) {
 fbuffer_append ( buffer , "null" , 4 ) ;
 }


static void tcg_out_tlb_check (TCGContext *s, int r0, int r1, int r2, int addr_reg, int addr_reg2, int s_bits, int offset1, int offset2, uint8_t **label_ptr) { uint16_t retranst; tcg_out32 (s, (RLWINM | RA (r0) | RS (addr_reg) | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS)) | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS)) | ME (31 - CPU_TLB_ENTRY_BITS) ) ); tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0)); tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset1 ) ); tcg_out32 (s, (RLWINM | RA (r2) | RS (addr_reg) | SH (0) | MB ((32 - s_bits) & 31) | ME (31 - TARGET_PAGE_BITS) ) ); tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1)); #if TARGET_LONG_BITS == 64 tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4); tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1)); tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); #endif /* Use a conditional branch-and-link so that we load a pointer to somewhere within the current opcode, for passing on to the helper. This address cannot be used for a tail call, but it's shorter than forming an address from scratch. */ *label_ptr = s->code_ptr; retranst = ((uint16_t *) s->code_ptr)[1] & ~3; tcg_out32(s, BC | BI(7, CR_EQ) | retranst | BO_COND_FALSE | LK); /* r0 now contains &env->tlb_table[mem_index][index].addr_x */ tcg_out32 (s, (LWZ | RT (r0) | RA (r0) | offset2 ) ); /* r0 = env->tlb_table[mem_index][index].addend */ tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg)); /* r0 = env->tlb_table[mem_index][index].addend + addr */ }


tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){

	tsize_t written=0;
	unsigned char* buffer=NULL;
	unsigned char* samplebuffer=NULL;
	tsize_t bufferoffset=0;
	tsize_t samplebufferoffset=0;
	tsize_t read=0;
	tstrip_t i=0;
	tstrip_t j=0;
	tstrip_t stripcount=0;
	tsize_t stripsize=0;
	tsize_t sepstripcount=0;
	tsize_t sepstripsize=0;
#ifdef OJPEG_SUPPORT
	toff_t inputoffset=0;
	uint16 h_samp=1;
	uint16 v_samp=1;
	uint16 ri=1;
	uint32 rows=0;
#endif /* ifdef OJPEG_SUPPORT */
#ifdef JPEG_SUPPORT
	unsigned char* jpt;
	float* xfloatp;
	uint64* sbc;
	unsigned char* stripbuffer;
	tsize_t striplength=0;
	uint32 max_striplength=0;
#endif /* ifdef JPEG_SUPPORT */

	/* Fail if prior error (in particular, can't trust tiff_datasize) */
	if (t2p->t2p_error != T2P_ERR_OK)
		return(0);

	if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){
#ifdef CCITT_SUPPORT
		if(t2p->pdf_compression == T2P_COMPRESS_G4){
			buffer = (unsigned char*)
				_TIFFmalloc(t2p->tiff_datasize);
			if (buffer == NULL) {
				TIFFError(TIFF2PDF_MODULE,
                                          "Can't allocate %lu bytes of memory for "
                                          "t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
			TIFFReadRawStrip(input, 0, (tdata_t) buffer,
					 t2p->tiff_datasize);
			if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){
					/*
					 * make sure is lsb-to-msb
					 * bit-endianness fill order
					 */
					TIFFReverseBits(buffer,
							t2p->tiff_datasize);
			}
			t2pWriteFile(output, (tdata_t) buffer,
				      t2p->tiff_datasize);
			_TIFFfree(buffer);
			return(t2p->tiff_datasize);
		}
#endif /* ifdef CCITT_SUPPORT */
#ifdef ZIP_SUPPORT
		if (t2p->pdf_compression == T2P_COMPRESS_ZIP) {
			buffer = (unsigned char*)
				_TIFFmalloc(t2p->tiff_datasize);
			if(buffer == NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
                        memset(buffer, 0, t2p->tiff_datasize);
			TIFFReadRawStrip(input, 0, (tdata_t) buffer,
					 t2p->tiff_datasize);
			if (t2p->tiff_fillorder==FILLORDER_LSB2MSB) {
					TIFFReverseBits(buffer,
							t2p->tiff_datasize);
			}
			t2pWriteFile(output, (tdata_t) buffer,
				      t2p->tiff_datasize);
			_TIFFfree(buffer);
			return(t2p->tiff_datasize);
		}
#endif /* ifdef ZIP_SUPPORT */
#ifdef OJPEG_SUPPORT
		if(t2p->tiff_compression == COMPRESSION_OJPEG) {

			if(t2p->tiff_dataoffset != 0) {
				buffer = (unsigned char*)
					_TIFFmalloc(t2p->tiff_datasize);
				if(buffer == NULL) {
					TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
						(unsigned long) t2p->tiff_datasize,
						TIFFFileName(input));
					t2p->t2p_error = T2P_ERR_ERROR;
					return(0);
				}
                                memset(buffer, 0, t2p->tiff_datasize);
				if(t2p->pdf_ojpegiflength==0){
					inputoffset=t2pSeekFile(input, 0,
								 SEEK_CUR);
					t2pSeekFile(input,
						     t2p->tiff_dataoffset,
						     SEEK_SET);
					t2pReadFile(input, (tdata_t) buffer,
						     t2p->tiff_datasize);
					t2pSeekFile(input, inputoffset,
						     SEEK_SET);
					t2pWriteFile(output, (tdata_t) buffer,
						      t2p->tiff_datasize);
					_TIFFfree(buffer);
					return(t2p->tiff_datasize);
				} else {
					inputoffset=t2pSeekFile(input, 0,
								 SEEK_CUR);
					t2pSeekFile(input,
						     t2p->tiff_dataoffset,
						     SEEK_SET);
					bufferoffset = t2pReadFile(input,
						(tdata_t) buffer,
						t2p->pdf_ojpegiflength);
					t2p->pdf_ojpegiflength = 0;
					t2pSeekFile(input, inputoffset,
						     SEEK_SET);
					TIFFGetField(input,
						     TIFFTAG_YCBCRSUBSAMPLING,
						     &h_samp, &v_samp);
					buffer[bufferoffset++]= 0xff;
					buffer[bufferoffset++]= 0xdd;
					buffer[bufferoffset++]= 0x00;
					buffer[bufferoffset++]= 0x04;
					h_samp*=8;
					v_samp*=8;
					ri=(t2p->tiff_width+h_samp-1) / h_samp;
					TIFFGetField(input,
						     TIFFTAG_ROWSPERSTRIP,
						     &rows);
					ri*=(rows+v_samp-1)/v_samp;
					buffer[bufferoffset++]= (ri>>8) & 0xff;
					buffer[bufferoffset++]= ri & 0xff;
					stripcount=TIFFNumberOfStrips(input);
					for(i=0;i<stripcount;i++){
						if(i != 0 ){
							buffer[bufferoffset++]=0xff;
							buffer[bufferoffset++]=(0xd0 | ((i-1)%8));
						}
						bufferoffset+=TIFFReadRawStrip(input,
							i,
							(tdata_t) &(((unsigned char*)buffer)[bufferoffset]),
							-1);
					}
					t2pWriteFile(output, (tdata_t) buffer, bufferoffset);
					_TIFFfree(buffer);
					return(bufferoffset);
				}
			} else {
				if(! t2p->pdf_ojpegdata){
					TIFFError(TIFF2PDF_MODULE,
				"No support for OJPEG image %s with bad tables",
						TIFFFileName(input));
					t2p->t2p_error = T2P_ERR_ERROR;
					return(0);
				}
				buffer = (unsigned char*)
					_TIFFmalloc(t2p->tiff_datasize);
				if(buffer==NULL){
					TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
						(unsigned long) t2p->tiff_datasize,
						TIFFFileName(input));
					t2p->t2p_error = T2P_ERR_ERROR;
					return(0);
				}
                                memset(buffer, 0, t2p->tiff_datasize);
				_TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength);
				bufferoffset=t2p->pdf_ojpegdatalength;
				stripcount=TIFFNumberOfStrips(input);
				for(i=0;i<stripcount;i++){
					if(i != 0){
						buffer[bufferoffset++]=0xff;
						buffer[bufferoffset++]=(0xd0 | ((i-1)%8));
					}
					bufferoffset+=TIFFReadRawStrip(input,
						i,
						(tdata_t) &(((unsigned char*)buffer)[bufferoffset]),
						-1);
				}
				if( ! ( (buffer[bufferoffset-1]==0xd9) && (buffer[bufferoffset-2]==0xff) ) ){
						buffer[bufferoffset++]=0xff;
						buffer[bufferoffset++]=0xd9;
				}
				t2pWriteFile(output, (tdata_t) buffer, bufferoffset);
				_TIFFfree(buffer);
				return(bufferoffset);
#if 0
                                /*
                                  This hunk of code removed code is clearly
                                  mis-placed and we are not sure where it
                                  should be (if anywhere)
                                */
				TIFFError(TIFF2PDF_MODULE,
	"No support for OJPEG image %s with no JPEG File Interchange offset",
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
#endif
			}
		}
#endif /* ifdef OJPEG_SUPPORT */
#ifdef JPEG_SUPPORT
		if(t2p->tiff_compression == COMPRESSION_JPEG) {
			uint32 count = 0;
			buffer = (unsigned char*)
				_TIFFmalloc(t2p->tiff_datasize);
			if(buffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
                        memset(buffer, 0, t2p->tiff_datasize);
			if (TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) {
				if(count > 4) {
					_TIFFmemcpy(buffer, jpt, count);
					bufferoffset += count - 2;
				}
			}
			stripcount=TIFFNumberOfStrips(input);
			TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc);
			for(i=0;i<stripcount;i++){
				if(sbc[i]>max_striplength) max_striplength=sbc[i];
			}
			stripbuffer = (unsigned char*)
				_TIFFmalloc(max_striplength);
			if(stripbuffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s",
					max_striplength,
					TIFFFileName(input));
				_TIFFfree(buffer);
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
			for(i=0;i<stripcount;i++){
				striplength=TIFFReadRawStrip(input, i, (tdata_t) stripbuffer, -1);
				if(!t2p_process_jpeg_strip(
					stripbuffer,
					&striplength,
					buffer,
					&bufferoffset,
					i,
					t2p->tiff_length)){
						TIFFError(TIFF2PDF_MODULE,
				"Can't process JPEG data in input file %s",
							TIFFFileName(input));
						_TIFFfree(samplebuffer);
						_TIFFfree(buffer);
						t2p->t2p_error = T2P_ERR_ERROR;
						return(0);
				}
			}
			buffer[bufferoffset++]=0xff;
			buffer[bufferoffset++]=0xd9;
			t2pWriteFile(output, (tdata_t) buffer, bufferoffset);
			_TIFFfree(stripbuffer);
			_TIFFfree(buffer);
			return(bufferoffset);
		}
#endif /* ifdef JPEG_SUPPORT */
		(void)0;
	}

	if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){
		buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
		if(buffer==NULL){
			TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
				(unsigned long) t2p->tiff_datasize,
				TIFFFileName(input));
			t2p->t2p_error = T2P_ERR_ERROR;
			return(0);
		}
                memset(buffer, 0, t2p->tiff_datasize);
		stripsize=TIFFStripSize(input);
		stripcount=TIFFNumberOfStrips(input);
		for(i=0;i<stripcount;i++){
			read =
				TIFFReadEncodedStrip(input,
				i,
				(tdata_t) &buffer[bufferoffset],
				TIFFmin(stripsize, t2p->tiff_datasize - bufferoffset));
			if(read==-1){
				TIFFError(TIFF2PDF_MODULE,
					"Error on decoding strip %u of %s",
					i,
					TIFFFileName(input));
				_TIFFfree(buffer);
				t2p->t2p_error=T2P_ERR_ERROR;
				return(0);
			}
			bufferoffset+=read;
		}
	} else {
		if(t2p->pdf_sample & T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG){

			sepstripsize=TIFFStripSize(input);
			sepstripcount=TIFFNumberOfStrips(input);

			stripsize=sepstripsize*t2p->tiff_samplesperpixel;
			stripcount=sepstripcount/t2p->tiff_samplesperpixel;

			buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
			if(buffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
                        memset(buffer, 0, t2p->tiff_datasize);
			samplebuffer = (unsigned char*) _TIFFmalloc(stripsize);
			if(samplebuffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
                                _TIFFfree(buffer);
				return(0);
			}
			for(i=0;i<stripcount;i++){
				samplebufferoffset=0;
				for(j=0;j<t2p->tiff_samplesperpixel;j++){
					read =
						TIFFReadEncodedStrip(input,
							i + j*stripcount,
							(tdata_t) &(samplebuffer[samplebufferoffset]),
							TIFFmin(sepstripsize, stripsize - samplebufferoffset));
					if(read==-1){
						TIFFError(TIFF2PDF_MODULE,
					"Error on decoding strip %u of %s",
							i + j*stripcount,
							TIFFFileName(input));
							_TIFFfree(buffer);
						t2p->t2p_error=T2P_ERR_ERROR;
						return(0);
					}
					samplebufferoffset+=read;
				}
				t2p_sample_planar_separate_to_contig(
					t2p,
					&(buffer[bufferoffset]),
					samplebuffer,
					samplebufferoffset);
				bufferoffset+=samplebufferoffset;
			}
			_TIFFfree(samplebuffer);
			goto dataready;
		}

		buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
		if(buffer==NULL){
			TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
				(unsigned long) t2p->tiff_datasize,
				TIFFFileName(input));
			t2p->t2p_error = T2P_ERR_ERROR;
			return(0);
		}
                memset(buffer, 0, t2p->tiff_datasize);
		stripsize=TIFFStripSize(input);
		stripcount=TIFFNumberOfStrips(input);
		for(i=0;i<stripcount;i++){
			read =
				TIFFReadEncodedStrip(input,
				i,
				(tdata_t) &buffer[bufferoffset],
				TIFFmin(stripsize, t2p->tiff_datasize - bufferoffset));
			if(read==-1){
				TIFFError(TIFF2PDF_MODULE,
					"Error on decoding strip %u of %s",
					i,
					TIFFFileName(input));
				_TIFFfree(samplebuffer);
				_TIFFfree(buffer);
				t2p->t2p_error=T2P_ERR_ERROR;
				return(0);
			}
			bufferoffset+=read;
		}

		if(t2p->pdf_sample & T2P_SAMPLE_REALIZE_PALETTE){
			// FIXME: overflow?
			samplebuffer=(unsigned char*)_TIFFrealloc(
				(tdata_t) buffer,
				t2p->tiff_datasize * t2p->tiff_samplesperpixel);
			if(samplebuffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				_TIFFfree(buffer);
				return(0);
			} else {
				buffer=samplebuffer;
				t2p->tiff_datasize *= t2p->tiff_samplesperpixel;
			}
			t2p_sample_realize_palette(t2p, buffer);
		}

		if(t2p->pdf_sample & T2P_SAMPLE_RGBA_TO_RGB){
			t2p->tiff_datasize=t2p_sample_rgba_to_rgb(
				(tdata_t)buffer,
				t2p->tiff_width*t2p->tiff_length);
		}

		if(t2p->pdf_sample & T2P_SAMPLE_RGBAA_TO_RGB){
			t2p->tiff_datasize=t2p_sample_rgbaa_to_rgb(
				(tdata_t)buffer,
				t2p->tiff_width*t2p->tiff_length);
		}

		if(t2p->pdf_sample & T2P_SAMPLE_YCBCR_TO_RGB){
			samplebuffer=(unsigned char*)_TIFFrealloc(
				(tdata_t)buffer,
				t2p->tiff_width*t2p->tiff_length*4);
			if(samplebuffer==NULL){
				TIFFError(TIFF2PDF_MODULE,
	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s",
					(unsigned long) t2p->tiff_datasize,
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				_TIFFfree(buffer);
				return(0);
			} else {
				buffer=samplebuffer;
			}
			if(!TIFFReadRGBAImageOriented(
				input,
				t2p->tiff_width,
				t2p->tiff_length,
				(uint32*)buffer,
				ORIENTATION_TOPLEFT,
				0)){
				TIFFError(TIFF2PDF_MODULE,
	"Can't use TIFFReadRGBAImageOriented to extract RGB image from %s",
					TIFFFileName(input));
				t2p->t2p_error = T2P_ERR_ERROR;
				return(0);
			}
			t2p->tiff_datasize=t2p_sample_abgr_to_rgb(
				(tdata_t) buffer,
				t2p->tiff_width*t2p->tiff_length);

		}

		if(t2p->pdf_sample & T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED){
			t2p->tiff_datasize=t2p_sample_lab_signed_to_unsigned(
				(tdata_t)buffer,
				t2p->tiff_width*t2p->tiff_length);
		}
	}

dataready:

	t2p_disable(output);
	TIFFSetField(output, TIFFTAG_PHOTOMETRIC, t2p->tiff_photometric);
	TIFFSetField(output, TIFFTAG_BITSPERSAMPLE, t2p->tiff_bitspersample);
	TIFFSetField(output, TIFFTAG_SAMPLESPERPIXEL, t2p->tiff_samplesperpixel);
	TIFFSetField(output, TIFFTAG_IMAGEWIDTH, t2p->tiff_width);
	TIFFSetField(output, TIFFTAG_IMAGELENGTH, t2p->tiff_length);
	TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, t2p->tiff_length);
	TIFFSetField(output, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(output, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);

	switch(t2p->pdf_compression){
	case T2P_COMPRESS_NONE:
		TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
		break;
#ifdef CCITT_SUPPORT
	case T2P_COMPRESS_G4:
		TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
		break;
#endif /* ifdef CCITT_SUPPORT */
#ifdef JPEG_SUPPORT
	case T2P_COMPRESS_JPEG:
		if(t2p->tiff_photometric==PHOTOMETRIC_YCBCR) {
			uint16 hor = 0, ver = 0;
			if (TIFFGetField(input, TIFFTAG_YCBCRSUBSAMPLING, &hor, &ver) !=0 ) {
				if(hor != 0 && ver != 0){
					TIFFSetField(output, TIFFTAG_YCBCRSUBSAMPLING, hor, ver);
				}
			}
			if(TIFFGetField(input, TIFFTAG_REFERENCEBLACKWHITE, &xfloatp)!=0){
				TIFFSetField(output, TIFFTAG_REFERENCEBLACKWHITE, xfloatp);
			}
		}
		if(TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_JPEG)==0){
			TIFFError(TIFF2PDF_MODULE,
		"Unable to use JPEG compression for input %s and output %s",
				TIFFFileName(input),
				TIFFFileName(output));
			_TIFFfree(buffer);
			t2p->t2p_error = T2P_ERR_ERROR;
			return(0);
		}
		TIFFSetField(output, TIFFTAG_JPEGTABLESMODE, 0);

		if(t2p->pdf_colorspace & (T2P_CS_RGB | T2P_CS_LAB)){
			TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
			if(t2p->tiff_photometric != PHOTOMETRIC_YCBCR){
				TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
			} else {
				TIFFSetField(output, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW);
			}
		}
		if(t2p->pdf_colorspace & T2P_CS_GRAY){
			(void)0;
		}
		if(t2p->pdf_colorspace & T2P_CS_CMYK){
			(void)0;
		}
		if(t2p->pdf_defaultcompressionquality != 0){
			TIFFSetField(output,
				TIFFTAG_JPEGQUALITY,
				t2p->pdf_defaultcompressionquality);
		}

		break;
#endif /* ifdef JPEG_SUPPORT */
#ifdef ZIP_SUPPORT
	case T2P_COMPRESS_ZIP:
		TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
		if(t2p->pdf_defaultcompressionquality%100 != 0){
			TIFFSetField(output,
				TIFFTAG_PREDICTOR,
				t2p->pdf_defaultcompressionquality % 100);
		}
		if(t2p->pdf_defaultcompressionquality/100 != 0){
			TIFFSetField(output,
				TIFFTAG_ZIPQUALITY,
				(t2p->pdf_defaultcompressionquality / 100));
		}
		break;
#endif /* ifdef ZIP_SUPPORT */
	default:
		break;
	}

	t2p_enable(output);
	t2p->outputwritten = 0;
#ifdef JPEG_SUPPORT
	if(t2p->pdf_compression == T2P_COMPRESS_JPEG
	   && t2p->tiff_photometric == PHOTOMETRIC_YCBCR){
		bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t)0,
						     buffer,
						     stripsize * stripcount);
	} else
#endif /* ifdef JPEG_SUPPORT */
        {
		bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t)0,
						     buffer,
						     t2p->tiff_datasize);
	}
	if (buffer != NULL) {
		_TIFFfree(buffer);
		buffer=NULL;
	}

	if (bufferoffset == (tsize_t)-1) {
		TIFFError(TIFF2PDF_MODULE,
			  "Error writing encoded strip to output PDF %s",
			  TIFFFileName(output));
		t2p->t2p_error = T2P_ERR_ERROR;
		return(0);
	}

	written = t2p->outputwritten;
	return(written);
}


void * xmlHashLookup3 ( xmlHashTablePtr table , const xmlChar * name , const xmlChar * name2 , const xmlChar * name3 ) {
 unsigned long key ;
 xmlHashEntryPtr entry ;
 if ( table == NULL ) return ( NULL ) ;
 if ( name == NULL ) return ( NULL ) ;
 key = xmlHashComputeKey ( table , name , name2 , name3 ) ;
 if ( table -> table [ key ] . valid == 0 ) return ( NULL ) ;
 if ( table -> dict ) {
 for ( entry = & ( table -> table [ key ] ) ;
 entry != NULL ;
 entry = entry -> next ) {
 if ( ( entry -> name == name ) && ( entry -> name2 == name2 ) && ( entry -> name3 == name3 ) ) return ( entry -> payload ) ;
 }
 }
 for ( entry = & ( table -> table [ key ] ) ;
 entry != NULL ;
 entry = entry -> next ) {
 if ( ( xmlStrEqual ( entry -> name , name ) ) && ( xmlStrEqual ( entry -> name2 , name2 ) ) && ( xmlStrEqual ( entry -> name3 , name3 ) ) ) return ( entry -> payload ) ;
 }
 return ( NULL ) ;
 }


void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
{
	struct llc_addr saddr, daddr;
	struct sock *sk;

	llc_pdu_decode_sa(skb, saddr.mac);
	llc_pdu_decode_ssap(skb, &saddr.lsap);
	llc_pdu_decode_da(skb, daddr.mac);
	llc_pdu_decode_dsap(skb, &daddr.lsap);

	sk = __llc_lookup(sap, &saddr, &daddr);
	if (!sk)
		goto drop;

	bh_lock_sock(sk);
	/*
	 * This has to be done here and not at the upper layer ->accept
	 * method because of the way the PROCOM state machine works:
	 * it needs to set several state variables (see, for instance,
	 * llc_adm_actions_2 in net/llc/llc_c_st.c) and send a packet to
	 * the originator of the new connection, and this state has to be
	 * in the newly created struct sock private area. -acme
	 */
	if (unlikely(sk->sk_state == TCP_LISTEN)) {
		struct sock *newsk = llc_create_incoming_sock(sk, skb->dev,
							      &saddr, &daddr);
		if (!newsk)
			goto drop_unlock;
		skb_set_owner_r(skb, newsk);
	} else {
		/*
		 * Can't be skb_set_owner_r, this will be done at the
		 * llc_conn_state_process function, later on, when we will use
		 * skb_queue_rcv_skb to send it to upper layers, this is
		 * another trick required to cope with how the PROCOM state
		 * machine works. -acme
		 */
		skb->sk = sk;
	}
	if (!sock_owned_by_user(sk))
		llc_conn_rcv(sk, skb);
	else {
		dprintk("%s: adding to backlog...\n", __func__);
		llc_set_backlog_type(skb, LLC_PACKET);
		if (sk_add_backlog(sk, skb, sk->sk_rcvbuf))
			goto drop_unlock;
	}
out:
	bh_unlock_sock(sk);
	sock_put(sk);
	return;
drop:
	kfree_skb(skb);
	return;
drop_unlock:
	kfree_skb(skb);
	goto out;
}