Exemple #1
0
static void write_header(void)
{
        int chksum;
        unsigned char * cp;

        /* Calculate and store the checksum (i.e., the sum of all of
           the bytes of the header).  The checksum field must be
           filled with blanks for the calculation.  The checksum field
           is formatted differently from the other fields: it has [6]
           digits, a null, then a space -- rather than digits,
           followed by a null like the other fields... */

        memset(tar.formated.chksum, ' ', sizeof(tar.formated.chksum));
        for (chksum = 0, cp = tar.raw; cp < tar.raw + 512; cp++)
            chksum += *cp;
        put_octal(tar.formated.chksum, 7, chksum);
        fwrite(tar.raw, sizeof(tar.raw), 1, archive);
        offset += sizeof(tar.raw);
}
Exemple #2
0
int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap )
{
   va_list args;
   size_t size;
   char c;

#ifndef __NO_ARGPOS__
   const char * fmt_start = format;
   v_param argbuf[ _ARGBUF_SIZE ];
   v_paramlst params;

   params.size = _ARGBUF_SIZE;
   params.maxarg = 0;
   params.arglst = argbuf;
#endif


#ifndef __NO_ARGPOS__
   do
   {
      params.repeat = HB_FALSE;
      if( params.maxarg > 0 )
      {
         va_copy( args, ap );
         va_arg_fill( &params, args );
         va_end( args );
      }
      format = fmt_start;
#endif
      va_copy( args, ap );
      size = 0;

      do
      {
         c = *format++;
         if( c == '%' )
         {
            const char * pattern = format;

            c = *format++;
            if( c != 0 && c != '%' )
            {
               /* decode pattern */
               v_param argval;
               int param = 0, flags = 0, width = -1, precision = -1, length,
                   value, stop = 0;

               /* parameter position */
               if( c >= '0' && c <= '9' )
               {
                  c = get_decimal( c, &format, &value );
                  if( c == '$' )
                     param = value;
                  else
                     format = pattern;
                  c = *format++;
               }

               /* flags */
               while( ! stop )
               {
                  switch( c )
                  {
                     case '#':
                        flags |= _F_ALTERNATE;
                        c = *format++;
                        break;
                     case '0':
                        flags |= _F_ZEROPADED;
                        c = *format++;
                        break;
                     case '-':
                        flags |= _F_LEFTADJUSTED;
                        c = *format++;
                        break;
                     case ' ':
                        flags |= _F_SPACE;
                        c = *format++;
                        break;
                     case '+':
                        flags |= _F_SIGN;
                        c = *format++;
                        break;
#ifdef _SUSV2_COMPAT_
                     case '\'':  /* group with locale thousands' grouping characters */
                        c = *format++;
                        break;
#endif
                     default:
                        stop = 1;
                        break;
                  }
               }

               /* field width */
               if( c == '*' )
               {
                  c = *format++;
                  if( c >= '0' && c <= '9' )
                  {
                     c = get_decimal( c, &format, &value );
                     if( c == '$' )
                     {
                        width = va_arg_n( args, _x_int, value );
                        c = *format++;
                     }
                     /* else error, wrong format */
                  }
                  else
                     width = va_arg_n( args, _x_int, 0 );
               }
               else if( c >= '0' && c <= '9' )
                  c = get_decimal( c, &format, &width );

               /* precision */
               if( c == '.' )
               {
                  precision = 0;
                  c = *format++;
                  if( c == '*' )
                  {
                     c = *format++;
                     if( c >= '0' && c <= '9' )
                     {
                        c = get_decimal( c, &format, &value );
                        if( c == '$' )
                        {
                           precision = va_arg_n( args, _x_int, value );
                           c = *format++;
                        }
                        /* else error, wrong format */
                     }
                     else
                        precision = va_arg_n( args, _x_int, 0 );
                  }
                  else if( c >= '0' && c <= '9' )
                     c = get_decimal( c, &format, &precision );
               }

               /* length modifier */
               switch( c )
               {
                  case 'h':
                     c = *format++;
                     if( c == 'h' )
                     {
                        length = _L_CHAR_;
                        c = *format++;
                     }
                     else
                        length = _L_SHORT_;
                     break;
                  case 'l':
                     c = *format++;
                     if( c == 'l' )
                     {
                        length = _L_LONGLONG_;
                        c = *format++;
                     }
                     else
                        length = _L_LONG_;
                     break;
                  case 'L':
                     length = _L_LONGDOUBLE_;
                     c = *format++;
                     break;
                  case 'j':
                     length = _L_INTMAX_;
                     c = *format++;
                     break;
                  case 'z':
                     length = _L_SIZE_;
                     c = *format++;
                     break;
                  case 't':
                     length = _L_PTRDIFF_;
                     c = *format++;
                     break;
                  case 'I':   /* MS-Windows extension */
                     if( format[ 0 ] == '6' && format[ 1 ] == '4' )
                     {
                        length = _L_LONGLONG_;
                        format += 2;
                        c = *format++;
                        break;
                     }
                     else if( format[ 0 ] == '1' && format[ 1 ] == '6' )
                     {
                        length = _L_SHORT_;
                        format += 2;
                        c = *format++;
                        break;
                     }
                     else if( format[ 0 ] == '3' && format[ 1 ] == '2' )
                     {
                        format += 2;
                        c = *format++;
                     }
                     /* no break; */
                  default:
                     length = _L_UNDEF_;
                     break;
               }

               /* conversion specifier */
               switch( c )
               {
#ifndef __NO_DOUBLE__
                  case 'a':
                  case 'A':
                  case 'e':
                  case 'E':
                  case 'g':
                  case 'G':
                     /* redirect above conversion to 'f' or 'F' type to keep
                      * valid parameters order
                      */
                     c = ( c == 'a' || c == 'e' || c == 'g' ) ? 'f' : 'F';
                     /* no break; */
                  case 'f':   /* double decimal notation */
                  case 'F':   /* double decimal notation */
                     if( length == _L_LONGDOUBLE_ )
                     {
                        argval.value.as_x_long_dbl = va_arg_n( args, _x_long_dbl, param );
                        HB_NUMTYPEL( value, argval.value.as_x_long_dbl );
                     }
                     else
                     {
                        double d = va_arg_n( args, _x_double, param );
                        HB_NUMTYPE( value, d );
                        argval.value.as_x_long_dbl =
                           ( value & ( _HB_NUM_NAN | _HB_NUM_PINF | _HB_NUM_NINF ) ) == 0 ? d : 0;
                     }
                     if( value & _HB_NUM_NAN )
                        size = put_str( buffer, bufsize, size,
                                        c == 'f' ?
                                        ( flags & _F_SIGN ? "+nan": "nan" ) :
                                        ( flags & _F_SIGN ? "+NAN": "NAN" ) ,
                                        flags, width, -1 );
                     else if( value & _HB_NUM_PINF )
                        size = put_str( buffer, bufsize, size,
                                        c == 'f' ?
                                        ( flags & _F_SIGN ? "+inf": "inf" ) :
                                        ( flags & _F_SIGN ? "+INF": "INF" ),
                                        flags, width, -1 );
                     else if( value & _HB_NUM_NINF )
                        size = put_str( buffer, bufsize, size,
                                        c == 'f' ? "-inf" : "-INF",
                                        flags, width, -1 );
                     else
                        size = put_dbl( buffer, bufsize, size, argval.value.as_x_long_dbl,
                                        flags, width, precision );
                     continue;
#endif
                  case 'd':
                  case 'i':   /* signed int decimal conversion */
                     if( length == _L_CHAR_ )
                        argval.value.as_x_intmax_t = ( unsigned char ) va_arg_n( args, _x_int, param );
                     else if( length == _L_SHORT_ )
                        argval.value.as_x_intmax_t = ( unsigned short ) va_arg_n( args, _x_int, param );
                     else if( length == _L_LONG_ )
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_long, param );
                     else if( length == _L_LONGLONG_ )
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_longlong, param );
                     else if( length == _L_INTMAX_ )
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_intmax_t, param );
                     else if( length == _L_SIZE_ )
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_size_t, param );
                     else if( length == _L_PTRDIFF_ )
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_ptrdiff_t, param );
                     else
                        argval.value.as_x_intmax_t = va_arg_n( args, _x_int, param );
                     value = argval.value.as_x_intmax_t < 0;
                     argval.value.as_x_uintmax_t = value ? -argval.value.as_x_intmax_t :
                                                            argval.value.as_x_intmax_t;
                     size = put_dec( buffer, bufsize, size, argval.value.as_x_uintmax_t,
                                     flags, width, precision, value );
                     continue;
                  case 'o':   /* unsigned int octal conversion */
                  case 'u':   /* unsigned int decimal conversion */
                  case 'x':   /* unsigned int hexadecimal conversion */
                  case 'X':   /* unsigned int hexadecimal conversion */
                     if( length == _L_CHAR_ )
                        argval.value.as_x_uintmax_t = ( unsigned char ) va_arg_n( args, _x_int, param );
                     else if( length == _L_SHORT_ )
                        argval.value.as_x_uintmax_t = ( unsigned short ) va_arg_n( args, _x_int, param );
                     else if( length == _L_LONG_ )
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_ulong, param );
                     else if( length == _L_LONGLONG_ )
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_ulonglong, param );
                     else if( length == _L_INTMAX_ )
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_uintmax_t, param );
                     else if( length == _L_SIZE_ )
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_size_t, param );
                     else if( length == _L_PTRDIFF_ )
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_ptrdiff_t, param );
                     else
                        argval.value.as_x_uintmax_t = va_arg_n( args, _x_uint, param );

                     if( c == 'o' )
                        size = put_octal( buffer, bufsize, size, argval.value.as_x_uintmax_t,
                                          flags, width, precision );
                     else if( c == 'u' )
                        size = put_dec( buffer, bufsize, size, argval.value.as_x_uintmax_t,
                                        flags & ~( _F_SPACE | _F_SIGN ),
                                        width, precision, 0 );
                     else
                        size = put_hex( buffer, bufsize, size, argval.value.as_x_uintmax_t,
                                        flags, width, precision, c == 'X' );
                     continue;
                  case 'p':   /* void * pointer */
                     argval.value.as_x_ptr = va_arg_n( args, _x_ptr, param );
                     if( argval.value.as_x_ptr )
                        size = put_hex( buffer, bufsize, size, ( HB_PTRUINT ) argval.value.as_x_ptr,
                                        flags | _F_ALTERNATE, width, precision, 0 );
                     else
                        size = put_str( buffer, bufsize, size, "(nil)",
                                        flags, width, -1 );
                     continue;
                  case 'c':   /* signed int casted to unsigned char */
                     if( ( flags & _F_LEFTADJUSTED ) == 0 )
                     {
                        while( --width > 0 )
                        {
                           if( size < bufsize )
                              buffer[ size ] = ' ';
                           ++size;
                        }
                     }
                     c = ( unsigned char ) va_arg_n( args, _x_int, param );
                     if( size < bufsize )
                        buffer[ size ] = c;
                     ++size;
                     while( --width > 0 )
                     {
                        if( size < bufsize )
                           buffer[ size ] = ' ';
                        ++size;
                     }
                     continue;
                  case 's':   /* const char * */
                     if( length == _L_LONG_ )
                     {
                        argval.value.as_x_wstr = va_arg_n( args, _x_wstr, param );
                        size = put_wstr( buffer, bufsize, size, argval.value.as_x_wstr,
                                         flags, width, precision );
                     }
                     else
                     {
                        argval.value.as_x_str = va_arg_n( args, _x_str, param );
                        size = put_str( buffer, bufsize, size, argval.value.as_x_str,
                                        flags, width, precision );
                     }
                     continue;
                  case 'n':   /* store current result size in int * arg */
                     /* This is very danger feature in *printf() functions
                      * family very often used by hackers to create buffer
                      * overflows. It can also cause unintentional memory
                      * corruption by programmers typo in pattern so if it's
                      * not strictly necessary it's good to disable it.
                      */
                     *( va_arg_n( args, _x_intptr, param ) ) = ( int ) size;
                     continue;
                  case '%':   /* store % consuming arguments % */
                     break;
                  default:    /* error, wrong format, store pattern */
                     format = pattern;
                     c = '%';
                     break;
               }
            }
         }

         /* ISO C99 defines that when size is 0 and buffer is NULL we should
          * return number of characters that would have been written in case
          * the output string has been large enough without trailing 0.
          * Many implementations always returns number of characters necessary
          * to hold the string even if the above condition is not true so the
          * returned value can be used to check if buffer was large enough
          * and if not to allocate bigger buffer. Let's do the same.
          */
         if( size < bufsize )
            buffer[ size ] = c;
         ++size;
      }
      while( c != 0 );

      va_end( args );

#ifndef __NO_ARGPOS__
   }
   while( params.repeat );

   if( params.arglst != argbuf )
      hb_xfree( params.arglst );
#endif

   /* always set trailing \0 !!! */
   if( bufsize )
      buffer[ bufsize - 1 ] = 0;

   return ( int ) ( size - 1 );
}