Estás en: Inicio >> Foros >> Informática >> Programación
Programación /

Autorizacion servidor SMTP en API WINDOWS

Participa en el tema Autorizacion servidor SMTP en API WINDOWS en el foro Programación.
Hola amigos , ando con un problemita que y no se como solucionarlo. estoy programando ...

Buscar en este tema:
1 2 >
 
  •  
    #1 Autorizacion servidor SMTP en API WINDOWS
    Hola amigos , ando con un problemita que y no se como solucionarlo.
    estoy programando un servidor del mail , y para poder enviar tengo que usar si o si el protocolo SMTP . estoy laburando en windows.
    el problema es que en el 99 cambiaron el protocolo y le agregaron un fase mas al proceso de enviar mail que es la fase de Autorizacion , el comando que se usa es el AUTH y segun pude leer existen 2 formas de poder hacerlo una es con un MD5 , y otra con CBASE 64 que son metodos de encriptacion el problema es que no se como hacerlo(implementarlo ) a nivel de api ,es lo unico que me falta del trabajo el reso supuestamente anda.
    NO PUEDO HACERLO CON MFC , tiene que se a nivel api como mucho, si alguien me puede ayudar se los agradeceria!!!!!!!
    Saludos
    +
     
    0
    Me gusta
     
    http://www.psicofxp.com/forums/programacion.313/52983-autorizacion-servidor-smtp-en-api-windows.html
    | Más
  • #2

    Aca tenes un par de libros sobre criptologia: http://www.kriptopolis.com/net/modul...download&cid=1

    Depaso fijate si este codigo te sirve de algo:
    [code]
    //
    /*
    ** nbench1.c
    */

    /********************************
    ** BYTEmark (tm) **
    ** BYTE NATIVE MODE BENCHMARKS **
    ** VERSION 2 **
    ** **
    ** Included in this source **
    ** file: **
    ** Numeric Heapsort **
    ** String Heapsort **
    ** Bitfield test **
    ** Floating point emulation **
    ** Fourier coefficients **
    ** Assignment algorithm **
    ** IDEA Encyption **
    ** Huffman compression **
    ** Back prop. neural net **
    ** LU Decomposition **
    ** (linear equations) **
    ** ---------- **
    ** Rick Grehan, BYTE Magazine **
    *********************************
    */

    /*
    ** INCLUDES
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include "nmglobal.h"
    #include "nbench1.h"
    #include "wordcat.h"

    /*
    #ifndef MAC
    #include <mem.h>
    #endif
    */

    //
    /*********************
    ** NUMERIC HEAPSORT **
    **********************
    ** This test implements a heapsort algorithm, performed on an
    ** array of longs.
    */

    /**************
    ** DoNumSort **
    ***************
    ** This routine performs the CPU numeric sort test.
    ** NOTE: Last version incorrectly stated that the routine
    ** returned result in # of longword sorted per second.
    ** Not so; the routine returns # of iterations per sec.
    */

    void DoNumSort(void)
    {
    SortStruct *numsortstruct; /* Local pointer to global struct */
    farlong *arraybase; /* Base pointers of array */
    long accumtime; /* Accumulated time */
    double iterations; /* Iteration counter */
    char *errorcontext; /* Error context string pointer */
    int systemerror; /* For holding error codes */

    /*
    ** Link to global structure
    */
    numsortstruct=&global_numsortstruct;

    /*
    ** Set the error context string.
    */
    errorcontext="CPU:Numeric Sort";

    /*
    ** See if we need to do self adjustment code.
    */
    if(numsortstruct->adjust==0)
    {
    /*
    ** Self-adjustment code. The system begins by sorting 1
    ** array. If it does that in no time, then two arrays
    ** are built and sorted. This process continues until
    ** enough arrays are built to handle the tolerance.
    */
    numsortstruct->numarrays=1;
    while(1)
    {
    /*
    ** Allocate space for arrays
    */
    arraybase=(farlong *)AllocateMemory(sizeof(long) *
    numsortstruct->numarrays * numsortstruct->arraysize,
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)arraybase,
    &systemerror);
    ErrorExit();
    }

    /*
    ** Do an iteration of the numeric sort. If the
    ** elapsed time is less than or equal to the permitted
    ** minimum, then allocate for more arrays and
    ** try again.
    */
    if(DoNumSortIteration(arraybase,
    numsortstruct->arraysize,
    numsortstruct->numarrays)>global_min_ticks)
    break; /* We're ok...exit */

    FreeMemory((farvoid *)arraybase,&systemerror);
    if(numsortstruct->numarrays++>NUMNUMARRAYS)
    { printf("CPU:NSORT -- NUMNUMARRAYS hit.\n");
    ErrorExit();
    }
    }
    }
    else
    { /*
    ** Allocate space for arrays
    */
    arraybase=(farlong *)AllocateMemory(sizeof(long) *
    numsortstruct->numarrays * numsortstruct->arraysize,
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)arraybase,
    &systemerror);
    ErrorExit();
    }

    }
    /*
    ** All's well if we get here. Repeatedly perform sorts until the
    ** accumulated elapsed time is greater than # of seconds requested.
    */
    accumtime=0L;
    iterations=(double)0.0;

    do {
    accumtime+=DoNumSortIteration(arraybase,
    numsortstruct->arraysize,
    numsortstruct->numarrays);
    iterations+=(double)1.0;
    } while(TicksToSecs(accumtime)<numsortstruct->request_secs);

    /*
    ** Clean up, calculate results, and go home. Be sure to
    ** show that we don't have to rerun adjustment code.
    */
    FreeMemory((farvoid *)arraybase,&systemerror);

    numsortstruct->sortspersec=iterations *
    (double)numsortstruct->numarrays / TicksToFracSecs(accumtime);

    if(numsortstruct->adjust==0)
    numsortstruct->adjust=1;

    return;
    }

    /***********************
    ** DoNumSortIteration **
    ************************
    ** This routine executes one iteration of the numeric
    ** sort benchmark. It returns the number of ticks
    ** elapsed for the iteration.
    */
    static ulong DoNumSortIteration(farlong *arraybase,
    ulong arraysize,
    uint numarrays)
    {
    ulong elapsed; /* Elapsed ticks */
    ulong i;
    /*
    ** Load up the array with random numbers
    */
    LoadNumArrayWithRand(arraybase,arraysize,numarrays );

    /*
    ** Start the stopwatch
    */
    elapsed=StartStopwatch();

    /*
    ** Execute a heap of heapsorts
    */
    for(i=0;i<numarrays;i++)
    NumHeapSort(arraybase+i*arraysize,0L,arraysize-1L);

    /*
    ** Get elapsed time
    */
    elapsed=StopStopwatch(elapsed);
    #ifdef DEBUG
    {

    for(i=0;i<arraysize-1;i++)
    { /*
    ** Compare to check for proper
    ** sort.
    */
    if(arraybase[i+1]<arraybase[i])
    { printf("Sort Error\n");
    break;
    }
    }
    }
    #endif

    return(elapsed);
    }

    /*************************
    ** LoadNumArrayWithRand **
    **************************
    ** Load up an array with random longs.
    */
    static void LoadNumArrayWithRand(farlong *array, /* Pointer to arrays */
    ulong arraysize,
    uint numarrays) /* # of elements in array */
    {
    long i; /* Used for index */
    farlong *darray; /* Destination array pointer */
    /*
    ** Initialize the random number generator
    */
    randnum(13L);

    /*
    ** Load up first array with randoms
    */
    for(i=0L;i<arraysize;i++)
    array[i]=randnum(0L);

    /*
    ** Now, if there's more than one array to load, copy the
    ** first into each of the others.
    */
    darray=array;
    while(--numarrays)
    { darray+=arraysize;
    for(i=0L;i<arraysize;i++)
    darray[i]=array[i];
    }

    return;
    }

    /****************
    ** NumHeapSort **
    *****************
    ** Pass this routine a pointer to an array of long
    ** integers. Also pass in minimum and maximum offsets.
    ** This routine performs a heap sort on that array.
    */
    static void NumHeapSort(farlong *array,
    ulong bottom, /* Lower bound */
    ulong top) /* Upper bound */
    {
    ulong temp; /* Used to exchange elements */
    ulong i; /* Loop index */

    /*
    ** First, build a heap in the array
    */
    for(i=(top/2L); i>0; --i)
    NumSift(array,i,top);

    /*
    ** Repeatedly extract maximum from heap and place it at the
    ** end of the array. When we get done, we'll have a sorted
    ** array.
    */
    for(i=top; i>0; --i)
    { NumSift(array,bottom,i);
    temp=*array; /* Perform exchange */
    *array=*(array+i);
    *(array+i)=temp;
    }
    return;
    }

    /************
    ** NumSift **
    *************
    ** Peforms the sift operation on a numeric array,
    ** constructing a heap in the array.
    */
    static void NumSift(farlong *array, /* Array of numbers */
    ulong i, /* Minimum of array */
    ulong j) /* Maximum of array */
    {
    unsigned long k;
    long temp; /* Used for exchange */

    while((i+i)<=j)
    {
    k=i+i;
    if(k<j)
    if(array[k]<array[k+1L])
    ++k;
    if(array[i]<array[k])
    {
    temp=array[k];
    array[k]=array[i];
    array[i]=temp;
    i=k;
    }
    else
    i=j+1;
    }
    return;
    }

    //
    /********************
    ** STRING HEAPSORT **
    ********************/

    /*****************
    ** DoStringSort **
    ******************
    ** This routine performs the CPU string sort test.
    ** Arguments:
    ** requested_secs = # of seconds to execute test
    ** stringspersec = # of strings per second sorted (RETURNED)
    */
    void DoStringSort(void)
    {

    SortStruct *strsortstruct; /* Local for sort structure */
    faruchar *arraybase; /* Base pointer of char array */
    long accumtime; /* Accumulated time */
    double iterations; /* # of iterations */
    char *errorcontext; /* Error context string pointer */
    int systemerror; /* For holding error code */

    /*
    ** Link to global structure
    */
    strsortstruct=&global_strsortstruct;

    /*
    ** Set the error context
    */
    errorcontext="CPU:String Sort";

    /*
    ** See if we have to perform self-adjustment code
    */
    if(strsortstruct->adjust==0)
    {
    /*
    ** Initialize the number of arrays.
    */
    strsortstruct->numarrays=1;
    while(1)
    {
    /*
    ** Allocate space for array. We'll add an extra 100
    ** bytes to protect memory as strings move around
    ** (this can happen during string adjustment)
    */
    arraybase=(faruchar *)AllocateMemory((strsortstruct->arraysize+100L) *
    (long)strsortstruct->numarrays,&systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    /*
    ** Do an iteration of the string sort. If the
    ** elapsed time is less than or equal to the permitted
    ** minimum, then de-allocate the array, reallocate a
    ** an additional array, and try again.
    */
    if(DoStringSortIteration(arraybase,
    strsortstruct->numarrays,
    strsortstruct->arraysize)>global_min_ticks)
    break; /* We're ok...exit */

    FreeMemory((farvoid *)arraybase,&systemerror);
    strsortstruct->numarrays+=1;
    }
    }
    else
    {
    /*
    ** We don't have to perform self adjustment code.
    ** Simply allocate the space for the array.
    */
    arraybase=(faruchar *)AllocateMemory((strsortstruct->arraysize+100L) *
    (long)strsortstruct->numarrays,&systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }
    }
    /*
    ** All's well if we get here. Repeatedly perform sorts until the
    ** accumulated elapsed time is greater than # of seconds requested.
    */
    accumtime=0L;
    iterations=(double)0.0;

    do {
    accumtime+=DoStringSortIteration(arraybase,
    strsortstruct->numarrays,
    strsortstruct->arraysize);
    iterations+=(double)strsortstruct->numarrays;
    } while(TicksToSecs(accumtime)<strsortstruct->request_secs);

    /*
    ** Clean up, calculate results, and go home.
    ** Set flag to show we don't need to rerun adjustment code.
    */
    FreeMemory((farvoid *)arraybase,&systemerror);
    strsortstruct->sortspersec=iterations / (double)TicksToFracSecs(accumtime);
    if(strsortstruct->adjust==0)
    strsortstruct->adjust=1;
    return;
    }

    /**************************
    ** DoStringSortIteration **
    ***************************
    ** This routine executes one iteration of the string
    ** sort benchmark. It returns the number of ticks
    ** Note that this routine also builds the offset pointer
    ** array.
    */
    static ulong DoStringSortIteration(faruchar *arraybase,
    uint numarrays,ulong arraysize)
    {
    farulong *optrarray; /* Offset pointer array */
    unsigned long elapsed; /* Elapsed ticks */
    unsigned long nstrings; /* # of strings in array */
    int syserror; /* System error code */
    unsigned int i; /* Index */
    farulong *tempobase; /* Temporary offset pointer base */
    faruchar *tempsbase; /* Temporary string base pointer */

    /*
    ** Load up the array(s) with random numbers
    */
    optrarray=LoadStringArray(arraybase,numarrays,&nst rings,arraysize);

    /*
    ** Set temp base pointers...they will be modified as the
    ** benchmark proceeds.
    */
    tempobase=optrarray;
    tempsbase=arraybase;

    /*
    ** Start the stopwatch
    */
    elapsed=StartStopwatch();

    /*
    ** Execute heapsorts
    */
    for(i=0;i<numarrays;i++)
    { StrHeapSort(tempobase,tempsbase,nstrings,0L,nstrin gs-1);
    tempobase+=nstrings; /* Advance base pointers */
    tempsbase+=arraysize+100;
    }

    /*
    ** Record elapsed time
    */
    elapsed=StopStopwatch(elapsed);

    #ifdef DEBUG
    {
    unsigned long i;
    for(i=0;i<nstrings-1;i++)
    { /*
    ** Compare strings to check for proper
    ** sort.
    */
    if(str_is_less(optrarray,arraybase,nstrings,i+1,i) )
    { printf("Sort Error\n");
    break;
    }
    }
    }
    #endif

    /*
    ** Release the offset pointer array built by
    ** LoadStringArray()
    */
    FreeMemory((farvoid *)optrarray,&syserror);

    /*
    ** Return elapsed ticks.
    */
    return(elapsed);
    }

    /********************
    ** LoadStringArray **
    *********************
    ** Initialize the string array with random strings of
    ** varying sizes.
    ** Returns the pointer to the offset pointer array.
    ** Note that since we're creating a number of arrays, this
    ** routine builds one array, then copies it into the others.
    */
    static farulong *LoadStringArray(faruchar *strarray, /* String array */
    uint numarrays, /* # of arrays */
    ulong *nstrings, /* # of strings */
    ulong arraysize) /* Size of array */
    {
    faruchar *tempsbase; /* Temporary string base pointer */
    farulong *optrarray; /* Local for pointer */
    farulong *tempobase; /* Temporary offset pointer base pointer */
    unsigned long curroffset; /* Current offset */
    int fullflag; /* Indicates full array */
    unsigned char stringlength; /* Length of string */
    unsigned char i; /* Index */
    unsigned long j; /* Another index */
    unsigned int k; /* Yet another index */
    unsigned int l; /* Ans still one more index */
    int systemerror; /* For holding error code */

    /*
    ** Initialize random number generator.
    */
    randnum(13L);

    /*
    ** Start with no strings. Initialize our current offset pointer
    ** to 0.
    */
    *nstrings=0L;
    curroffset=0L;
    fullflag=0;

    do
    {
    /*
    ** Allocate a string with a random length no
    ** shorter than 4 bytes and no longer than
    ** 80 bytes. Note we have to also make sure
    ** there's room in the array.
    */
    stringlength=(unsigned char)(1+abs_randwc(76L) & 0xFFL);
    if((unsigned long)stringlength+curroffset+1L>=arraysize)
    { stringlength=(unsigned char)((arraysize-curroffset-1L) &
    0xFF);
    fullflag=1; /* Indicates a full */
    }

    /*
    ** Store length at curroffset and advance current offset.
    */
    *(strarray+curroffset)=stringlength;
    curroffset++;

    /*
    ** Fill up the rest of the string with random bytes.
    */
    for(i=0;i<stringlength;i++)
    { *(strarray+curroffset)=
    (unsigned char)(abs_randwc((long)0xFE));
    curroffset++;
    }

    /*
    ** Increment the # of strings counter.
    */
    *nstrings+=1L;

    } while(fullflag==0);

    /*
    ** We now have initialized a single full array. If there
    ** is more than one array, copy the original into the
    ** others.
    */
    k=1;
    tempsbase=strarray;
    while(k<numarrays)
    { tempsbase+=arraysize+100; /* Set base */
    for(l=0;l<arraysize;l++)
    tempsbase[l]=strarray[l];
    k++;
    }

    /*
    ** Now the array is full, allocate enough space for an
    ** offset pointer array.
    */
    optrarray=(farulong *)AllocateMemory(*nstrings * sizeof(unsigned long) *
    numarrays,
    &systemerror);
    if(systemerror)
    { ReportError("CPU:Stringsort",systemerror);
    FreeMemory((void *)strarray,&systemerror);
    ErrorExit();
    }

    /*
    ** Go through the newly-built string array, building
    ** offsets and putting them into the offset pointer
    ** array.
    */
    curroffset=0;
    for(j=0;j<*nstrings;j++)
    { *(optrarray+j)=curroffset;
    curroffset+=(unsigned long)(*(strarray+curroffset))+1L;
    }

    /*
    ** As above, we've made one copy of the offset pointers,
    ** so duplicate this array in the remaining ones.
    */
    k=1;
    tempobase=optrarray;
    while(k<numarrays)
    { tempobase+=*nstrings;
    for(l=0;l<*nstrings;l++)
    tempobase[l]=optrarray[l];
    k++;
    }

    /*
    ** All done...go home. Pass local pointer back.
    */
    return(optrarray);
    }

    /**************
    ** stradjust **
    ***************
    ** Used by the string heap sort. Call this routine to adjust the
    ** string at offset i to length l. The members of the string array
    ** are moved accordingly and the length of the string at offset i
    ** is set to l.
    */
    static void stradjust(farulong *optrarray, /* Offset pointer array */
    faruchar *strarray, /* String array */
    ulong nstrings, /* # of strings */
    ulong i, /* Offset to adjust */
    uchar l) /* New length */
    {
    unsigned long nbytes; /* # of bytes to move */
    unsigned long j; /* Index */
    int direction; /* Direction indicator */
    unsigned char adjamount; /* Adjustment amount */

    /*
    ** If new length is less than old length, the direction is
    ** down. If new length is greater than old length, the
    ** direction is up.
    */
    direction=(int)l - (int)*(strarray+*(optrarray+i));
    adjamount=(unsigned char)abs(direction);

    /*
    ** See if the adjustment is being made to the last
    ** string in the string array. If so, we don't have to
    ** do anything more than adjust the length field.
    */
    if(i==(nstrings-1L))
    { *(strarray+*(optrarray+i))=l;
    return;
    }

    /*
    ** Calculate the total # of bytes in string array from
    ** location i+1 to end of array. Whether we're moving "up" or
    ** down, this is how many bytes we'll have to move.
    */
    nbytes=*(optrarray+nstrings-1L) +
    (unsigned long)*(strarray+*(optrarray+nstrings-1L)) + 1L -
    *(optrarray+i+1L);

    /*
    ** Calculate the source and the destination. Source is
    ** string position i+1. Destination is string position i+l
    ** (i+"ell"...don't confuse 1 and l).
    ** Hand this straight to memmove and let it handle the
    ** "overlap" problem.
    */
    MoveMemory((farvoid *)(strarray+*(optrarray+i)+l+1),
    (farvoid *)(strarray+*(optrarray+i+1)),
    (unsigned long)nbytes);

    /*
    ** We have to adjust the offset pointer array.
    ** This covers string i+1 to numstrings-1.
    */
    for(j=i+1;j<nstrings;j++)
    if(direction<0)
    *(optrarray+j)=*(optrarray+j)-adjamount;
    else
    *(optrarray+j)=*(optrarray+j)+adjamount;

    /*
    ** Store the new length and go home.
    */
    *(strarray+*(optrarray+i))=l;
    return;
    }

    /****************
    ** strheapsort **
    *****************
    ** Pass this routine a pointer to an array of unsigned char.
    ** The array is presumed to hold strings occupying at most
    ** 80 bytes (counts a byte count).
    ** This routine also needs a pointer to an array of offsets
    ** which represent string locations in the array, and
    ** an unsigned long indicating the number of strings
    ** in the array.
    */
    static void StrHeapSort(farulong *optrarray, /* Offset pointers */
    faruchar *strarray, /* Strings array */
    ulong numstrings, /* # of strings in array */
    ulong bottom, /* Region to sort...bottom */
    ulong top) /* Region to sort...top */
    {
    unsigned char temp[80]; /* Used to exchange elements */
    unsigned char tlen; /* Temp to hold length */
    unsigned long i; /* Loop index */


    /*
    ** Build a heap in the array
    */
    for(i=(top/2L); i>0; --i)
    strsift(optrarray,strarray,numstrings,i,top);

    /*
    ** Repeatedly extract maximum from heap and place it at the
    ** end of the array. When we get done, we'll have a sorted
    ** array.
    */
    for(i=top; i>0; --i)
    {
    strsift(optrarray,strarray,numstrings,0,i);

    /* temp = string[0] */
    tlen=*strarray;
    MoveMemory((farvoid *)&temp[0], /* Perform exchange */
    (farvoid *)strarray,
    (unsigned long)(tlen+1));


    /* string[0]=string[i] */
    tlen=*(strarray+*(optrarray+i));
    stradjust(optrarray,strarray,numstrings,0,tlen);
    MoveMemory((farvoid *)strarray,
    (farvoid *)(strarray+*(optrarray+i)),
    (unsigned long)(tlen+1));

    /* string[i]=temp */
    tlen=temp[0];
    stradjust(optrarray,strarray,numstrings,i,tlen);
    MoveMemory((farvoid *)(strarray+*(optrarray+i)),
    (farvoid *)&temp[0],
    (unsigned long)(tlen+1));

    }
    return;
    }

    /****************
    ** str_is_less **
    *****************
    ** Pass this function:
    ** 1) A pointer to an array of offset pointers
    ** 2) A pointer to a string array
    ** 3) The number of elements in the string array
    ** 4) Offsets to two strings (a & b)
    ** This function returns TRUE if string a is < string b.
    */
    static int str_is_less(farulong *optrarray, /* Offset pointers */
    faruchar *strarray, /* String array */
    ulong numstrings, /* # of strings */
    ulong a, ulong b) /* Offsets */
    {
    int slen; /* String length */

    /*
    ** Determine which string has the minimum length. Use that
    ** to call strncmp(). If they match up to that point, the
    ** string with the longer length wins.
    */
    slen=(int)*(strarray+*(optrarray+a));
    if(slen > (int)*(strarray+*(optrarray+b)))
    slen=(int)*(strarray+*(optrarray+b));

    slen=strncmp((char *)(strarray+*(optrarray+a)),
    (char *)(strarray+*(optrarray+b)),slen);

    if(slen==0)
    {
    /*
    ** They match. Return true if the length of a
    ** is greater than the length of b.
    */
    if(*(strarray+*(optrarray+a)) >
    *(strarray+*(optrarray+b)))
    return(TRUE);
    return(FALSE);
    }

    if(slen<0) return(TRUE); /* a is strictly less than b */

    return(FALSE); /* Only other possibility */
    }

    /************
    ** strsift **
    *************
    ** Pass this function:
    ** 1) A pointer to an array of offset pointers
    ** 2) A pointer to a string array
    ** 3) The number of elements in the string array
    ** 4) Offset within which to sort.
    ** Sift the array within the bounds of those offsets (thus
    ** building a heap).
    */
    static void strsift(farulong *optrarray, /* Offset pointers */
    faruchar *strarray, /* String array */
    ulong numstrings, /* # of strings */
    ulong i, ulong j) /* Offsets */
    {
    unsigned long k; /* Temporaries */
    unsigned char temp[80];
    unsigned char tlen; /* For string lengths */


    while((i+i)<=j)
    {
    k=i+i;
    if(k<j)
    if(str_is_less(optrarray,strarray,numstrings,k,k+1 L))
    ++k;
    if(str_is_less(optrarray,strarray,numstrings,i,k))
    {
    /* temp=string[k] */
    tlen=*(strarray+*(optrarray+k));
    MoveMemory((farvoid *)&temp[0],
    (farvoid *)(strarray+*(optrarray+k)),
    (unsigned long)(tlen+1));

    /* string[k]=string[i] */
    tlen=*(strarray+*(optrarray+i));
    stradjust(optrarray,strarray,numstrings,k,tlen);
    MoveMemory((farvoid *)(strarray+*(optrarray+k)),
    (farvoid *)(strarray+*(optrarray+i)),
    (unsigned long)(tlen+1));

    /* string[i]=temp */
    tlen=temp[0];
    stradjust(optrarray,strarray,numstrings,i,tlen);
    MoveMemory((farvoid *)(strarray+*(optrarray+i)),
    (farvoid *)&temp[0],
    (unsigned long)(tlen+1));
    i=k;
    }
    else
    i=j+1;
    }
    return;
    }

    //
    /************************
    ** BITFIELD OPERATIONS **
    *************************/

    /*************
    ** DoBitops **
    **************
    ** Perform the bit operations test portion of the CPU
    ** benchmark. Returns the iterations per second.
    */
    void DoBitops(void)
    {
    BitOpStruct *locbitopstruct; /* Local bitop structure */
    farulong *bitarraybase; /* Base of bitmap array */
    farulong *bitoparraybase; /* Base of bitmap operations array */
    ulong nbitops; /* # of bitfield operations */
    ulong accumtime; /* Accumulated time in ticks */
    double iterations; /* # of iterations */
    char *errorcontext; /* Error context string */
    int systemerror; /* For holding error codes */

    /*
    ** Link to global structure.
    */
    locbitopstruct=&global_bitopstruct;

    /*
    ** Set the error context.
    */
    errorcontext="CPU:Bitfields";

    /*
    ** See if we need to run adjustment code.
    */
    if(locbitopstruct->adjust==0)
    {
    bitarraybase=(farulong *)AllocateMemory(locbitopstruct->bitfieldarraysize *
    sizeof(ulong),&systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    /*
    ** Initialize bitfield operations array to [2,30] elements
    */
    locbitopstruct->bitoparraysize=30L;

    while(1)
    {
    /*
    ** Allocate space for operations array
    */
    bitoparraybase=(farulong *)AllocateMemory(locbitopstruct->bitoparraysize*2L*
    sizeof(ulong),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)bitarraybase,&systemerror);
    ErrorExit();
    }
    /*
    ** Do an iteration of the bitmap test. If the
    ** elapsed time is less than or equal to the permitted
    ** minimum, then de-allocate the array, reallocate a
    ** larger version, and try again.
    */
    if(DoBitfieldIteration(bitarraybase,
    bitoparraybase,
    locbitopstruct->bitoparraysize,
    &nbitops)>global_min_ticks)
    break; /* We're ok...exit */

    FreeMemory((farvoid *)bitoparraybase,&systemerror);
    locbitopstruct->bitoparraysize+=100L;
    }
    }
    else
    {
    /*
    ** Don't need to do self adjustment, just allocate
    ** the array space.
    */
    bitarraybase=(farulong *)AllocateMemory(locbitopstruct->bitfieldarraysize *
    sizeof(ulong),&systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }
    bitoparraybase=(farulong *)AllocateMemory(locbitopstruct->bitoparraysize*2L*
    sizeof(ulong),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)bitarraybase,&systemerror);
    ErrorExit();
    }
    }

    /*
    ** All's well if we get here. Repeatedly perform bitops until the
    ** accumulated elapsed time is greater than # of seconds requested.
    */
    accumtime=0L;
    iterations=(double)0.0;
    do {
    accumtime+=DoBitfieldIteration(bitarraybase,
    bitoparraybase,
    locbitopstruct->bitoparraysize,&nbitops);
    iterations+=(double)nbitops;
    } while(TicksToSecs(accumtime)<locbitopstruct->request_secs);

    /*
    ** Clean up, calculate results, and go home.
    ** Also, set adjustment flag to show that we don't have
    ** to do self adjusting in the future.
    */
    FreeMemory((farvoid *)bitarraybase,&systemerror);
    FreeMemory((farvoid *)bitoparraybase,&systemerror);
    locbitopstruct->bitopspersec=iterations /TicksToFracSecs(accumtime);
    if(locbitopstruct->adjust==0)
    locbitopstruct->adjust=1;

    return;
    }

    /************************
    ** DoBitfieldIteration **
    *************************
    ** Perform a single iteration of the bitfield benchmark.
    ** Return the # of ticks accumulated by the operation.
    */
    static ulong DoBitfieldIteration(farulong *bitarraybase,
    farulong *bitoparraybase,
    long bitoparraysize,
    ulong *nbitops)
    {
    long i; /* Index */
    ulong bitoffset; /* Offset into bitmap */
    ulong elapsed; /* Time to execute */

    /*
    ** Clear # bitops counter
    */
    *nbitops=0L;

    /*
    ** Construct a set of bitmap offsets and run lengths.
    ** The offset can be any random number from 0 to the
    ** size of the bitmap (in bits). The run length can
    ** be any random number from 1 to the number of bits
    ** between the offset and the end of the bitmap.
    ** Note that the bitmap has 8192 * 32 bits in it.
    ** (262,144 bits)
    */
    for (i=0;i<bitoparraysize;i++)
    {
    /* First item is offset */
    *(bitoparraybase+i+i)=bitoffset=abs_randwc(262140L );

    /* Next item is run length */
    *nbitops+=*(bitoparraybase+i+i+1L)=abs_randwc(2621 40L-bitoffset);
    }

    /*
    ** Array of offset and lengths built...do an iteration of
    ** the test.
    ** Start the stopwatch.
    */
    elapsed=StartStopwatch();

    /*
    ** Loop through array off offset/run length pairs.
    ** Execute operation based on modulus of index.
    */
    for(i=0;i<bitoparraysize;i++)
    {
    switch(i % 3)
    {

    case 0: /* Set run of bits */
    ToggleBitRun(bitarraybase,
    *(bitoparraybase+i+i),
    *(bitoparraybase+i+i+1),
    1);
    break;

    case 1: /* Clear run of bits */
    ToggleBitRun(bitarraybase,
    *(bitoparraybase+i+i),
    *(bitoparraybase+i+i+1),
    0);
    break;

    case 2: /* Complement run of bits */
    FlipBitRun(bitarraybase,
    *(bitoparraybase+i+i),
    *(bitoparraybase+i+i+1));
    break;
    }
    }

    /*
    ** Return elapsed time
    */
    return(StopStopwatch(elapsed));
    }


    /*****************************
    ** ToggleBitRun *
    ******************************
    ** Set or clear a run of nbits starting at
    ** bit_addr in bitmap.
    */
    static void ToggleBitRun(farulong *bitmap, /* Bitmap */
    ulong bit_addr, /* Address of bits to set */
    ulong nbits, /* # of bits to set/clr */
    uint val) /* 1 or 0 */
    {
    unsigned long bindex; /* Index into array */
    unsigned long bitnumb; /* Bit number */

    while(nbits--)
    {
    #ifdef LONG64
    bindex=bit_addr>>6; /* Index is number /64 */
    bindex=bit_addr % 64; /* Bit number in word */
    #else
    bindex=bit_addr>>5; /* Index is number /32 */
    bitnumb=bit_addr % 32; /* bit number in word */
    #endif
    if(val)
    bitmap[bindex]|=(1L<<bitnumb);
    else
    bitmap[bindex]&=~(1L<<bitnumb);
    bit_addr++;
    }
    return;
    }

    /***************
    ** FlipBitRun **
    ****************
    ** Complements a run of bits.
    */
    static void FlipBitRun(farulong *bitmap, /* Bit map */
    ulong bit_addr, /* Bit address */
    ulong nbits) /* # of bits to flip */
    {
    unsigned long bindex; /* Index into array */
    unsigned long bitnumb; /* Bit number */

    while(nbits--)
    {
    #ifdef LONG64
    bindex=bit_addr>>6; /* Index is number /64 */
    bitnumb=bit_addr % 32; /* Bit number in longword */
    #else
    bindex=bit_addr>>5; /* Index is number /32 */
    bitnumb=bit_addr % 32; /* Bit number in longword */
    #endif
    bitmap[bindex]^=(1L<<bitnumb);
    bit_addr++;
    }

    return;
    }

    //
    /*****************************
    ** FLOATING-POINT EMULATION **
    *****************************/

    /**************
    ** DoEmFloat **
    ***************
    ** Perform the floating-point emulation routines portion of the
    ** CPU benchmark. Returns the operations per second.
    */
    void DoEmFloat(void)
    {
    EmFloatStruct *locemfloatstruct; /* Local structure */
    InternalFPF *abase; /* Base of A array */
    InternalFPF *bbase; /* Base of B array */
    InternalFPF *cbase; /* Base of C array */
    ulong accumtime; /* Accumulated time in ticks */
    double iterations; /* # of iterations */
    ulong tickcount; /* # of ticks */
    char *errorcontext; /* Error context string pointer */
    int systemerror; /* For holding error code */
    ulong loops; /* # of loops */

    /*
    ** Link to global structure
    */
    locemfloatstruct=&global_emfloatstruct;

    /*
    ** Set the error context
    */
    errorcontext="CPU:Floating Emulation";


    /*
    ** Test the emulation routines.
    */
    #ifdef DEBUG
    #endif

    abase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    bbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)abase,&systemerror);
    ErrorExit();
    }

    cbase=(InternalFPF *)AllocateMemory(locemfloatstruct->arraysize*sizeof(InternalFPF),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)abase,&systemerror);
    FreeMemory((farvoid *)bbase,&systemerror);
    ErrorExit();
    }

    /*
    ** Set up the arrays
    */
    SetupCPUEmFloatArrays(abase,bbase,cbase,locemfloat struct->arraysize);

    /*
    ** See if we need to do self-adjusting code.
    */
    if(locemfloatstruct->adjust==0)
    {
    locemfloatstruct->loops=0;

    /*
    ** Do an iteration of the tests. If the elapsed time is
    ** less than minimum, increase the loop count and try
    ** again.
    */
    for(loops=1;loops<CPUEMFLOATLOOPMAX;loops+=loops)
    { tickcount=DoEmFloatIteration(abase,bbase,cbase,
    locemfloatstruct->arraysize,
    loops);
    if(tickcount>global_min_ticks)
    { locemfloatstruct->loops=loops;
    break;
    }
    }
    }

    /*
    ** Verify that selft adjustment code worked.
    */
    if(locemfloatstruct->loops==0)
    { printf("CPU:EMFPU -- CMPUEMFLOATLOOPMAX limit hit\n");
    FreeMemory((farvoid *)abase,&systemerror);
    FreeMemory((farvoid *)bbase,&systemerror);
    FreeMemory((farvoid *)cbase,&systemerror);
    ErrorExit();
    }

    /*
    ** All's well if we get here. Repeatedly perform floating
    ** tests until the accumulated time is greater than the
    ** # of seconds requested.
    ** Each iteration performs arraysize * 3 operations.
    */
    accumtime=0L;
    iterations=(double)0.0;
    do {
    accumtime+=DoEmFloatIteration(abase,bbase,cbase,
    locemfloatstruct->arraysize,
    locemfloatstruct->loops);
    iterations+=(double)1.0;
    } while(TicksToSecs(accumtime)<locemfloatstruct->request_secs);


    /*
    ** Clean up, calculate results, and go home.
    ** Also, indicate that adjustment is done.
    */
    FreeMemory((farvoid *)abase,&systemerror);
    FreeMemory((farvoid *)bbase,&systemerror);
    FreeMemory((farvoid *)cbase,&systemerror);

    locemfloatstruct->emflops=(iterations*(double)locemfloatstruct->loops)/
    (double)TicksToFracSecs(accumtime);
    if(locemfloatstruct->adjust==0)
    locemfloatstruct->adjust=1;

    return;
    }

    //
    /*************************
    ** FOURIER COEFFICIENTS **
    *************************/

    /**************
    ** DoFourier **
    ***************
    ** Perform the transcendental/trigonometric portion of the
    ** benchmark. This benchmark calculates the first n
    ** fourier coefficients of the function (x+1)^x defined
    ** on the interval 0,2.
    */
    void DoFourier(void)
    {
    FourierStruct *locfourierstruct; /* Local fourier struct */
    fardouble *abase; /* Base of A[] coefficients array */
    fardouble *bbase; /* Base of B[] coefficients array */
    unsigned long accumtime; /* Accumulated time in ticks */
    double iterations; /* # of iterations */
    char *errorcontext; /* Error context string pointer */
    int systemerror; /* For error code */

    /*
    ** Link to global structure
    */
    locfourierstruct=&global_fourierstruct;

    /*
    ** Set error context string
    */
    errorcontext="FPU:Transcendental";

    /*
    ** See if we need to do self-adjustment code.
    */
    if(locfourierstruct->adjust==0)
    {
    locfourierstruct->arraysize=100L; /* Start at 100 elements */
    while(1)
    {

    abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((void *)abase,&systemerror);
    ErrorExit();
    }
    /*
    ** Do an iteration of the tests. If the elapsed time is
    ** less than or equal to the permitted minimum, re-allocate
    ** larger arrays and try again.
    */
    if(DoFPUTransIteration(abase,bbase,
    locfourierstruct->arraysize)>global_min_ticks)
    break; /* We're ok...exit */

    /*
    ** Make bigger arrays and try again.
    */
    FreeMemory((farvoid *)abase,&systemerror);
    FreeMemory((farvoid *)bbase,&systemerror);
    locfourierstruct->arraysize+=50L;
    }
    }
    else
    { /*
    ** Don't need self-adjustment. Just allocate the
    ** arrays, and go.
    */
    abase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    bbase=(fardouble *)AllocateMemory(locfourierstruct->arraysize*sizeof(double),
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((void *)abase,&systemerror);
    ErrorExit();
    }
    }
    /*
    ** All's well if we get here. Repeatedly perform integration
    ** tests until the accumulated time is greater than the
    ** # of seconds requested.
    */
    accumtime=0L;
    iterations=(double)0.0;
    do {
    accumtime+=DoFPUTransIteration(abase,bbase,locfour ierstruct->arraysize);
    iterations+=(double)locfourierstruct->arraysize*(double)2.0-(double)1.0;
    } while(TicksToSecs(accumtime)<locfourierstruct->request_secs);


    /*
    ** Clean up, calculate results, and go home.
    ** Also set adjustment flag to indicate no adjust code needed.
    */
    FreeMemory((farvoid *)abase,&systemerror);
    FreeMemory((farvoid *)bbase,&systemerror);

    locfourierstruct->fflops=iterations/(double)TicksToFracSecs(accumtime);

    if(locfourierstruct->adjust==0)
    locfourierstruct->adjust=1;

    return;
    }

    /************************
    ** DoFPUTransIteration **
    *************************
    ** Perform an iteration of the FPU Transcendental/trigonometric
    ** benchmark. Here, an iteration consists of calculating the
    ** first n fourier coefficients of the function (x+1)^x on
    ** the interval 0,2. n is given by arraysize.
    ** NOTE: The # of integration steps is fixed at
    ** 200.
    */
    static ulong DoFPUTransIteration(fardouble *abase, /* A coeffs. */
    fardouble *bbase, /* B coeffs. */
    ulong arraysize) /* # of coeffs */
    {
    double omega; /* Fundamental frequency */
    unsigned long i; /* Index */
    unsigned long elapsed; /* Elapsed time */

    /*
    ** Start the stopwatch
    */
    elapsed=StartStopwatch();

    /*
    ** Calculate the fourier series. Begin by
    ** calculating A[0].
    */

    *abase=TrapezoidIntegrate((double)0.0,
    (double)2.0,
    200,
    (double)0.0, /* No omega * n needed */
    0 )/(double)2.0;

    /*
    ** Calculate the fundamental frequency.
    ** ( 2 * pi ) / period...and since the period
    ** is 2, omega is simply pi.
    */
    omega=(double)3.1415926535897932;

    for(i=1;i<arraysize;i++)
    {

    /*
    ** Calculate A[i] terms. Note, once again, that we
    ** can ignore the 2/period term outside the integral
    ** since the period is 2 and the term cancels itself
    ** out.
    */
    *(abase+i)=TrapezoidIntegrate((double)0.0,
    (double)2.0,
    200,
    omega * (double)i,
    1);

    /*
    ** Calculate the B[i] terms.
    */
    *(bbase+i)=TrapezoidIntegrate((double)0.0,
    (double)2.0,
    200,
    omega * (double)i,
    2);

    }

    /*
    ** All done, stop the stopwatch
    */
    return(StopStopwatch(elapsed));
    }

    /***********************
    ** TrapezoidIntegrate **
    ************************
    ** Perform a simple trapezoid integration on the
    ** function (x+1)**x.
    ** x0,x1 set the lower and upper bounds of the
    ** integration.
    ** nsteps indicates # of trapezoidal sections
    ** omegan is the fundamental frequency times
    ** the series member #
    ** select = 0 for the A[0] term, 1 for cosine terms, and
    ** 2 for sine terms.
    ** Returns the value.
    */
    static double TrapezoidIntegrate( double x0, /* Lower bound */
    double x1, /* Upper bound */
    int nsteps, /* # of steps */
    double omegan, /* omega * n */
    int select)
    {
    double x; /* Independent variable */
    double dx; /* Stepsize */
    double rvalue; /* Return value */


    /*
    ** Initialize independent variable
    */
    x=x0;

    /*
    ** Calculate stepsize
    */
    dx=(x1 - x0) / (double)nsteps;

    /*
    ** Initialize the return value.
    */
    rvalue=thefunction(x0,omegan,select)/(double)2.0;

    /*
    ** Compute the other terms of the integral.
    */
    if(nsteps!=1)
    { --nsteps; /* Already done 1 step */
    while(--nsteps )
    {
    x+=dx;
    rvalue+=thefunction(x,omegan,select);
    }
    }
    /*
    ** Finish computation
    */
    rvalue=(rvalue+thefunction(x1,omegan,select)/(double)2.0)*dx;

    return(rvalue);
    }

    /****************
    ** thefunction **
    *****************
    ** This routine selects the function to be used
    ** in the Trapezoid integration.
    ** x is the independent variable
    ** omegan is omega * n
    ** select chooses which of the sine/cosine functions
    ** are used. note the special case for select=0.
    */
    static double thefunction(double x, /* Independent variable */
    double omegan, /* Omega * term */
    int select) /* Choose term */
    {

    /*
    ** Use select to pick which function we call.
    */
    switch(select)
    {
    case 0: return(pow(x+(double)1.0,x));

    case 1: return(pow(x+(double)1.0,x) * cos(omegan * x));

    case 2: return(pow(x+(double)1.0,x) * sin(omegan * x));
    }

    /*
    ** We should never reach this point, but the following
    ** keeps compilers from issuing a warning message.
    */
    return(0.0);
    }

    //
    /*************************
    ** ASSIGNMENT ALGORITHM **
    *************************/

    /*************
    ** DoAssign **
    **************
    ** Perform an assignment algorithm.
    ** The algorithm was adapted from the step by step guide found
    ** in "Quantitative Decision Making for Business" (Gordon,
    ** Pressman, and Cohn; Prentice-Hall)
    **
    **
    ** NOTES:
    ** 1. Even though the algorithm distinguishes between
    ** ASSIGNROWS and ASSIGNCOLS, as though the two might
    ** be different, it does presume a square matrix.
    ** I.E., ASSIGNROWS and ASSIGNCOLS must be the same.
    ** This makes for some algorithmically-correct but
    ** probably non-optimal constructs.
    **
    */
    void DoAssign(void)
    {
    AssignStruct *locassignstruct; /* Local structure ptr */
    farlong *arraybase;
    char *errorcontext;
    int systemerror;
    ulong accumtime;
    double iterations;

    /*
    ** Link to global structure
    */
    locassignstruct=&global_assignstruct;

    /*
    ** Set the error context string.
    */
    errorcontext="CPU:Assignment";

    /*
    ** See if we need to do self adjustment code.
    */
    if(locassignstruct->adjust==0)
    {
    /*
    ** Self-adjustment code. The system begins by working on 1
    ** array. If it does that in no time, then two arrays
    ** are built. This process continues until
    ** enough arrays are built to handle the tolerance.
    */
    locassignstruct->numarrays=1;
    while(1)
    {
    /*
    ** Allocate space for arrays
    */
    arraybase=(farlong *) AllocateMemory(sizeof(long)*
    ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays,
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)arraybase,
    &systemerror);
    ErrorExit();
    }

    /*
    ** Do an iteration of the assignment alg. If the
    ** elapsed time is less than or equal to the permitted
    ** minimum, then allocate for more arrays and
    ** try again.
    */
    if(DoAssignIteration(arraybase,
    locassignstruct->numarrays)>global_min_ticks)
    break; /* We're ok...exit */

    FreeMemory((farvoid *)arraybase, &systemerror);
    locassignstruct->numarrays++;
    }
    }
    else
    { /*
    ** Allocate space for arrays
    */
    arraybase=(farlong *)AllocateMemory(sizeof(long)*
    ASSIGNROWS*ASSIGNCOLS*locassignstruct->numarrays,
    &systemerror);
    if(systemerror)
    { ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)arraybase,
    &systemerror);
    ErrorExit();
    }
    }

    /*
    ** All's well if we get here. Do the tests.
    */
    accumtime=0L;
    iterations=(double)0.0;

    do {
    accumtime+=DoAssignIteration(arraybase,
    locassignstruct->numarrays);
    iterations+=(double)1.0;
    } while(TicksToSecs(accumtime)<locassignstruct->request_secs);

    /*
    ** Clean up, calculate results, and go home. Be sure to
    ** show that we don't have to rerun adjustment code.
    */
    FreeMemory((farvoid *)arraybase,&systemerror);

    locassignstruct->iterspersec=iterations *
    (double)locassignstruct->numarrays / TicksToFracSecs(accumtime);

    if(locassignstruct->adjust==0)
    locassignstruct->adjust=1;

    return;

    }

    /**********************
    ** DoAssignIteration **
    ***********************
    ** This routine executes one iteration of the assignment test.
    ** It returns the number of ticks elapsed in the iteration.
    */
    static ulong DoAssignIteration(farlong *arraybase,
    ulong numarrays)
    {
    longptr abase; /* local pointer */
    ulong elapsed; /* Elapsed ticks */
    ulong i;

    /*
    ** Set up local pointer
    */
    abase.ptrs.p=arraybase;

    /*
    ** Load up the arrays with a random table.
    */
    LoadAssignArrayWithRand(arraybase,numarrays);

    /*
    ** Start the stopwatch
    */
    elapsed=StartStopwatch();

    /*
    ** Execute assignment algorithms
    */
    for(i=0;i<numarrays;i++)
    { abase.ptrs.p+=i*ASSIGNROWS*ASSIGNCOLS;
    Assignment(*abase.ptrs.ap);
    }

    /*
    ** Get elapsed time
    */
    return(StopStopwatch(elapsed));
    }

    /****************************
    ** LoadAssignArrayWithRand **
    *****************************
    ** Load the assignment arrays with random numbers. All positive.
    ** These numbers represent costs.
    */
    static void LoadAssignArrayWithRand(farlong *arraybase,
    ulong numarrays)
    {
    longptr abase,abase1; /* Local for array pointer */
    ulong i;

    /*
    ** Set local array pointer
    */
    abase.ptrs.p=arraybase;
    abase1.ptrs.p=arraybase;

    /*
    ** Set up the first array. Then just copy it into the
    ** others.
    */
    LoadAssign(*(abase.ptrs.ap));
    if(numarrays>1)
    for(i=1;i<numarrays;i++)
    { abase1.ptrs.p+=i*ASSIGNROWS*ASSIGNCOLS;
    CopyToAssign(*(abase.ptrs.ap),*(abase1.ptrs.ap));
    }

    return;
    }

    /***************
    ** LoadAssign **
    ****************
    ** The array given by arraybase is loaded with positive random
    ** numbers. Elements in the array are capped at 5,000,000.
    */
    static void LoadAssign(farlong arraybase[][ASSIGNCOLS])
    {
    ushort i,j;

    /*
    ** Reset random number generator so things repeat.
    */
    randnum(13L);

    for(i=0;i<ASSIGNROWS;i++)
    for(j=0;j<ASSIGNROWS;j++)
    arraybase[i][j]=abs_randwc(5000000L);
    return;
    }

    /*****************
    ** CopyToAssign **
    ******************
    ** Copy the contents of one array to another. This is called by
    ** the routine that builds the initial array, and is used to copy
    ** the contents of the intial array into all following arrays.
    */
    static void CopyToAssign(farlong arrayfrom[ASSIGNROWS][ASSIGNCOLS],
    farlong arrayto[ASSIGNROWS][ASSIGNCOLS])
    {
    ushort i,j;

    for(i=0;i<ASSIGNROWS;i++)
    for(j=0;j<ASSIGNCOLS;j++)
    arrayto[i][j]=arrayfrom[i][j];

    return;
    }

    /***************
    ** Assignment **
    ***************/
    static void Assignment(farlong arraybase[][ASSIGNCOLS])
    {
    short assignedtableau[ASSIGNROWS][ASSIGNCOLS];

    /*
    ** First, calculate minimum costs
    */
    calc_minimum_costs(arraybase);

    /*
    ** Repeat following until the number of rows selected
    ** equals the number of rows in the tableau.
    */
    while(first_assignments(arraybase,assignedtableau) !=ASSIGNROWS)
    { second_assignments(arraybase,assignedtableau);
    }

    #ifdef DEBUG
    {
    int i,j;
    printf("Column choices for each row\n");
    for(i=0;i<ASSIGNROWS;i++)
    {
    for(j=0;j<ASSIGNCOLS;j++)
    if(assignedtableau[i][j]!=0)
    printf("%d ",j);
    }
    }
    #endif

    return;
    }

    /***********************
    ** calc_minimum_costs **
    ************************
    ** Revise the tableau by calculating the minimum costs on a
    ** row and column basis. These minima are subtracted from
    ** their rows and columns, creating a new tableau.
    */
    static void calc_minimum_costs(long tableau[][ASSIGNCOLS])
    {
    ushort i,j; /* Index variables */
    long currentmin; /* Current minimum */
    /*
    ** Determine minimum costs on row basis. This is done by
    ** subtracting -- on a row-per-row basis -- the minum value
    ** for that row.
    */
    for(i=0;i<ASSIGNROWS;i++)
    {
    currentmin=MAXPOSLONG; /* Initialize minimum */
    for(j=0;j<ASSIGNCOLS;j++)
    if(tableau[i][j]<currentmin)
    currentmin=tableau[i][j];

    for(j=0;j<ASSIGNCOLS;j++)
    tableau[i][j]-=currentmin;
    }

    /*
    ** Determine minimum cost on a column basis. This works
    ** just as above, only now we step through the array
    ** column-wise
    */
    for(j=0;j<ASSIGNCOLS;j++)
    {
    currentmin=MAXPOSLONG; /* Initialize minimum */
    for(i=0;i<ASSIGNROWS;i++)
    if(tableau[i][j]<currentmin)
    currentmin=tableau[i][j];

    /*
    ** Here, we'll take the trouble to see if the current
    ** minimum is zero. This is likely worth it, since the
    ** preceding loop will have created at least one zero in
    ** each row. We can save ourselves a few iterations.
    */
    if(currentmin!=0)
    for(i=0;i<ASSIGNROWS;i++)
    tableau[i][j]-=currentmin;
    }

    return;
    }

    /**********************
    ** first_assignments **
    ***********************
    ** Do first assignments.
    ** The assignedtableau[] array holds a set of values that
    ** indicate the assignment of a value, or its elimination.
    ** The values are:
    ** 0 = Item is neither assigned nor eliminated.
    ** 1 = Item is assigned
    ** 2 = Item is eliminated
    ** Returns the number of selections made. If this equals
    ** the number of rows, then an optimum has been determined.
    */
    static int first_assignments(long tableau[][ASSIGNCOLS],
    short assignedtableau[][ASSIGNCOLS])
    {
    ushort i,j,k; /* Index variables */
    ushort numassigns; /* # of assignments */
    ushort totnumassigns; /* Total # of assignments */
    ushort numzeros; /* # of zeros in row */
    int selected; /* Flag used to indicate selection */

    /*
    ** Clear the assignedtableau, setting all members to show that
    ** no one is yet assigned, eliminated, or anything.
    */
    for(i=0;i<ASSIGNROWS;i++)
    for(j=0;j<ASSIGNCOLS;j++)
    assignedtableau[i][j]=0;

    totnumassigns=0;
    do {
    numassigns=0;
    /*
    ** Step through rows. For each one that is not currently
    ** assigned, see if the row has only one zero in it. If so,
    ** mark that as an assigned row/col. Eliminate other zeros
    ** in the same column.
    */
    for(i=0;i<ASSIGNROWS;i++)
    { numzeros=0;
    for(j=0;j<ASSIGNCOLS;j++)
    if(tableau[i][j]==0L)
    if(assignedtableau[i][j]==0)
    { numzeros++;
    selected=j;
    }
    if(numzeros==1)
    { numassigns++;
    totnumassigns++;
    assignedtableau[i][selected]=1;
    for(k=0;k<ASSIGNROWS;k++)
    if((k!=i) &&
    (tableau[k][selected]==0))
    assignedtableau[k][selected]=2;
    }
    }
    /*
    ** Step through columns, doing same as above. Now, be careful
    ** of items in the other rows of a selected column.
    */
    for(j=0;j<ASSIGNCOLS;j++)
    { numzeros=0;
    for(i=0;i<ASSIGNROWS;i++)
    if(tableau[i][j]==0L)
    if(assignedtableau[i][j]==0)
    { numzeros++;
    selected=i;
    }
    if(numzeros==1)
    { numassigns++;
    totnumassigns++;
    assignedtableau[selected][j]=1;
    for(k=0;k<ASSIGNCOLS;k++)
    if((k!=j) &&
    (tableau[selected][k]==0))
    assignedtableau[selected][k]=2;
    }
    }
    /*
    ** Repeat until no more assignments to be made.
    */
    } while(numassigns!=0);

    /*
    ** See if we can leave at this point.
    */
    if(totnumassigns==ASSIGNROWS) return(totnumassigns);

    /*
    ** Now step through the array by row. If you find any unassigned
    ** zeros, pick the first in the row. Eliminate all zeros from
    ** that same row & column. This occurs if there are multiple optima...
    ** possibly.
    */
    for(i=0;i<ASSIGNROWS;i++)
    { selected=-1;
    for(j=0;j<ASSIGNCOLS;j++)
    if((tableau[i][j]==0L) &&
    (assignedtableau[i][j]==0))
    { selected=j;
    break;
    }
    if(selected!=-1)
    { assignedtableau[i][selected]=1;
    totnumassigns++;
    for(k=0;k<ASSIGNCOLS;k++)
    if((k!=selected) &&
    (tableau[i][k]==0L))
    assignedtableau[i][k]=2;
    for(k=0;k<ASSIGNROWS;k++)
    if((k!=i) &&
    (tableau[k][selected]==0L))
    assignedtableau[k][selected]=2;
    }
    }

    return(totnumassigns);
    }

    /***********************
    ** second_assignments **
    ************************
    ** This section of the algorithm creates the revised
    ** tableau, and is difficult to explain. I suggest you
    ** refer to the algorithm's source, mentioned in comments
    ** toward the beginning of the program.
    */
    static void second_assignments(long tableau[][ASSIGNCOLS],
    short assignedtableau[][ASSIGNCOLS])
    {
    int i,j; /* Indexes */
    short linesrow[ASSIGNROWS];
    short linescol[ASSIGNCOLS];
    long smallest; /* Holds smallest value */
    ushort numassigns; /* Number of assignments */
    ushort newrows; /* New rows to be considered */
    /*
    ** Clear the linesrow and linescol arrays.
    */
    for(i=0;i<ASSIGNROWS;i++)
    linesrow[i]=0;
    for(i=0;i<ASSIGNCOLS;i++)
    linescol[i]=0;

    /*
    ** Scan rows, flag each row that has no assignment in it.
    */
    for(i=0;i<ASSIGNROWS;i++)
    { numassigns=0;
    for(j=0;j<ASSIGNCOLS;j++)
    if(assignedtableau[i][j]==1)
    { numassigns++;
    break;
    }
    if(numassigns==0) linesrow[i]=1;
    }

    do {

    newrows=0;
    /*
    ** For each row checked above, scan for any zeros. If found,
    ** check the associated column.
    */
    for(i=0;i<ASSIGNROWS;i++)
    { if(linesrow[i]==1)
    for(j=0;j<ASSIGNCOLS;j++)
    if(tableau[i][j]==0)
    linescol[j]=1;
    }

    /*
    ** Now scan checked columns. If any contain assigned zeros, check
    ** the associated row.
    */
    for(j=0;j<ASSIGNCOLS;j++)
    if(linescol[j]==1)
    for(i=0;i<ASSIGNROWS;i++)
    if((assignedtableau[i][j]==1) &&
    (linesrow[i]!=1))
    {
    linesrow[i]=1;
    newrows++;
    }
    } while(newrows!=0);

    /*
    ** linesrow[n]==0 indicate rows covered by imaginary line
    ** linescol[n]==1 indicate cols covered by imaginary line
    ** For all cells not covered by imaginary lines, determine smallest
    ** value.
    */
    smallest=MAXPOSLONG;
    for(i=0;i<ASSIGNROWS;i++)
    if(linesrow[i]!=0)
    for(j=0;j<ASSIGNCOLS;j++)
    if(linescol[j]!=1)
    if(tableau[i][j]<smallest)
    smallest=tableau[i][j];

    /*
    ** Subtract smallest from all cells in the above set.
    */
    for(i=0;i<ASSIGNROWS;i++)
    if(linesrow[i]!=0)
    for(j=0;j<ASSIGNCOLS;j++)
    if(linescol[j]!=1)
    tableau[i][j]-=smallest;

    /*
    ** Add smallest to all cells covered by two lines.
    */
    for(i=0;i<ASSIGNROWS;i++)
    if(linesrow[i]==0)
    for(j=0;j<ASSIGNCOLS;j++)
    if(linescol[j]==1)
    tableau[i][j]+=smallest;

    return;
    }

    //
    /********************
    ** IDEA Encryption **
    *********************
    ** IDEA - International Data Encryption Algorithm.
    ** Based on code presented in Applied Cryptography by Bruce Schneier.
    ** Which was based on code developed by Xuejia Lai and James L. Massey.
    ** Other modifications made by Colin Plumb.
    **
    */

    /***********
    ** DoIDEA **
    ************
    ** Perform IDEA encryption. Note that we time encryption & decryption
    ** time as being a single loop.
    */
    void DoIDEA(void)
    {
    IDEAStruct *locideastruct; /* Loc pointer to global structure */
    int i;
    IDEAkey Z,DK;
    u16 userkey[8];
    ulong accumtime;
    double iterations;
    char *errorcontext;
    int systemerror;
    faruchar *plain1; /* First plaintext buffer */
    faruchar *crypt1; /* Encryption buffer */
    faruchar *plain2; /* Second plaintext buffer */

    /*
    ** Link to global data
    */
    locideastruct=&global_ideastruct;

    /*
    ** Set error context
    */
    errorcontext="CPU:IDEA";

    /*
    ** Re-init random-number generator.
    */
    randnum(3L);

    /*
    ** Build an encryption/decryption key
    */
    for (i=0;i<8;i++)
    userkey[i]=(u16)(abs_randwc(60000L) & 0xFFFF);
    for(i=0;i<KEYLEN;i++)
    Z[i]=0;

    /*
    ** Compute encryption/decryption subkeys
    */
    en_key_idea(userkey,Z);
    de_key_idea(Z,DK);

    /*
    ** Allocate memory for buffers. We'll make 3, called plain1,
    ** crypt1, and plain2. It works like this:
    ** plain1 >>encrypt>> crypt1 >>decrypt>> plain2.
    ** So, plain1 and plain2 should match.
    ** Also, fill up plain1 with sample text.
    */
    plain1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror);
    if(systemerror)
    {
    ReportError(errorcontext,systemerror);
    ErrorExit();
    }

    crypt1=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror);
    if(systemerror)
    {
    ReportError(errorcontext,systemerror);
    FreeMemory((farvoid *)plain1,&systemerror);
    ErrorExit();
    }

    plain2=(faruchar *)AllocateMemory(locideastruct->arraysize,&systemerror);
    if(systemerror)
    {
    ReportError(errorconte
    Me gusta este mensaje
  • #3

    GRACIAS qwerty, de rebote me sirvio un par de algoritmos que andaba necesitando


    hoy a investigar en la pagina

    GRACIAS POR CONTESTAR!!!!!!!!!!!!
    Me gusta este mensaje
  • #4

    De nada, fijate que cualquier cosa abrimos el source de algun smtp server y vemos que es lo que te sirve .
    Me gusta este mensaje
  • #5

    continuo con problemas , no pueso pasar la fase de autorizacion en el servidor de SMTP la respuesta que me tira es

    250-smtp014.mail.yahoo.com
    250-AUTH LOGIN PLAIN
    250-PIPELINING
    250 8BITMIME

    yo le mando la siguiente linea
    AUTH LOGIN PLAIN

    y me devuelve como respuesta
    334 UGFzc3dvc

    despues de aca que le tengo que mandar??????
    como es la impementacion de LOGIN PLAIN, en todos lados uasan SASL de linux , yo necesito hacer esta autorizacion para windows
    alguien sabe que tengo que hacer con la respuesta

    Gracias!!!!!!!!!!!!!
    Me gusta este mensaje
  • #6

    Pasa el RFC asi me fijo y te digo. Yo el unico que me se de memoria es el del IRC y el draft del IRCX

    Attachalo y postea el link, aunque sea el numero.
    PD: Te fijaste en www.rfc-es.org haber si esta traducido, en castellano por ahi sea mas facil.
    Me gusta este mensaje
  • #7

    ok http://www.thecabal.org/~devin/postfix/smtp-auth.txt
    GRACIAS POR CONTESTAR , fijate que ahi esta mas o menos explicado el problema es que no puedo usar las librerias SASL
    Me gusta este mensaje
  • #8

    Trata de no basarte en documentos asi de descolgados. Fijate en los standards que te van a ahorrar mas de un dolor de cabeza:
    http://rfc.net/rfc-index.html
    Ahi estan todos, todos los aceptados por lo menos.

    La verdad no se como ayudarte porque no encuentro esa info de ahi aplicable al daemon, es decir no la entiendo.

    Perdona, despues por ahi mas despierto o con algo de cafeina ensima la reviso.

    Saludos.
    Me gusta este mensaje
  • #9

    GRacias qwerty
    Me gusta este mensaje
  • #10

    Gente gracias por ayudarme , especialmente vos qwerty ya lo pude solucionar!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    GRACIAS
    Me gusta este mensaje
1 2 >
Estás en: Inicio >> Foros >> Informática >> Programación


Estadísticas del tema
  • 10 RESPUESTAS
  • 316 VISTAS
  • 2 USUARIOS RESPONDIERON
 
Ir arriba
Contacto | Acerca de | Ayuda | Términos Legales | privacidad | Pautas de convivencia | Mapa de los foros | TrabajÁ con nosotros
©2008 Psicofxp.com S.A. - Todos los derechos reservados
Certifica IAB