**************************************** **********************************
Establish by lzh. a cgi program.
Get a file from user's explorer.
**************************************** ***********************************/
# Include <stdio. h>
# Include <string. h>
# Define deal_buf_len 1024.
# Define sign_code_len 100
# Define file_name_len 64
# Define file_save_dir "/var/log /"
Enum
{
State_start,
State_get_sign_code,
State_get_file_name,
State_get_file_start,
State_get_file_content,
State_check_end,
State_end
};
/*************************************** ************************************
Showerrorinfo
**************************************** ************************************/
Static void showerrorinfo (char * error)
{
Printf ("Content-Type: text/plain/n ");
Printf (error );
}
/* The subject starts from here */
Int main (void)
{
File * FP;/* file pointer, save the file we want to get */
Int getstate = state_start;
Int contentlength;/* length of standard input content */
Int nowreadlen;
Int signcodelen;
Int tmplen;
Char * nowreadp;
Char * nowwritep;
Char dealbuf [deal_buf_len];
Char signcode [sign_code_len];/* store this signature */
Char tmpsigncode [sign_code_len];
Char filename [file_name_len];
Memset (dealbuf, 0, deal_buf_len );
Memset (signcode, 0, sign_code_len );
Memset (filename, 0, file_name_len );
Nowreadlen = 0;
If (char *) getenv ("content_length ")! = NULL)
{
Contentlength = atoi (char *) getenv ("content_length "));
}
Else
{
Showerrorinfo ("no data! ");
Exit (1 );
}
While (contentlength> 0)
{
If (contentlength> = deal_buf_len)
{
Nowreadlen = deal_buf_len;
}
Else
{
Nowreadlen = contentlength;
}
Contentlength-= nowreadlen;
If (fread (dealbuf, sizeof (char), nowreadlen, stdin )! = Nowreadlen)
{
Showerrorinfo ("Data reading error! ");
Exit (1 );
}
Nowreadp = dealbuf;
While (nowreadlen> 0)
{
Switch (getstate)
{
Case state_start:
Nowwritep = signcode;
Getstate = state_get_sign_code;
Case state_get_sign_code:
If (strncmp (nowreadp, "/R/N", 2) = 0)
{
Signcodelen = nowwritep-signcode;
Nowreadp ++;
Nowreadlen --;
* Nowwritep = 0;
Getstate = state_get_file_name;
// Showerrorinfo (signcode );
}
Else
{
* Nowwritep = * nowreadp;
Nowwritep ++;
}
Break;
Case state_get_file_name:
If (strncmp (nowreadp, "filename =", strlen ("filename =") = 0)
{
Nowreadp + = strlen ("filename = ");
Nowreadlen-= strlen ("filename = ");
Nowwritep = filename + strlen (file_save_dir );
While (* nowreadp! = '/R ')
{
If (* nowreadp = '//')
{
Nowwritep = filename + strlen (file_save_dir );
}
Else if (* nowreadp! = '/"')
{
* Nowwritep = * nowreadp;
Nowwritep ++;
}
Nowreadp ++;
Nowreadlen --;
}
* Nowwritep = 0;
Nowreadp ++;
Nowreadlen --;
Getstate = state_get_file_start;
Memcpy (filename, file_save_dir, strlen (file_save_dir ));
If (FP = fopen (filename, "W") = NULL)
{
Fprintf (stderr, "Open File error/N ");
Exit (1 );
}
// Showerrorinfo (filename );
}
Break;
Case state_get_file_start:
If (strncmp (nowreadp, "/R/n/R/N", 4) = 0)
{
Nowreadp + = 3;
Nowreadlen-= 3;
Getstate = state_get_file_content;
// Showerrorinfo ("get ");
}
Break;
Case state_get_file_content:
If (* nowreadp! = '/R ')
{
Fputc (* nowreadp, FP );
}
Else
{
If (nowreadlen> = (signcodelen + 2 ))
{
If (strncmp (nowreadp + 2, signcode, signcodelen) = 0)
{
Getstate = state_end;
Nowreadlen = 1;
Showerrorinfo ("transfer completed ");
}
Else
{
Fputc (* nowreadp, FP );
}
}
Else
{
Getstate = state_check_end;
Nowwritep = tmpsigncode;
* Nowwritep = * nowreadp;
Nowwritep ++;
Tmplen = 1;
}
}
Break;
Case state_check_end:
If (* nowreadp! = '/R ')
{
If (tmplen <signcodelen + 2)
{
* Nowwritep = * nowreadp;
Nowwritep ++;
Tmplen ++;
If (tmplen = signcodelen + 2)
{
* Nowwritep = 0;
If (tmpsigncode [1] = '/N') & (strncmp (tmpsigncode + 2, signcode, signcodelen) = 0 ))
{
Getstate = state_end;
Nowreadlen = 1;
Showerrorinfo ("transfer completed ");
}
Else
{
// Fprintf (FP, tmpsigncode );
Fwrite (tmpsigncode, sizeof (char), tmplen, FP );
Getstate = state_get_file_content;
}
}
}
}
Else
{
* Nowwritep = 0;
// Fprintf (FP, tmpsigncode );
Fwrite (tmpsigncode, sizeof (char), tmplen, FP );
Nowwritep = tmpsigncode;
* Nowwritep = * nowreadp;
Nowwritep ++;
Tmplen = 1;
}
Break;
Case state_end:
Nowreadlen = 1;
Break;
Default: break;
}
Nowreadlen --;
Nowreadp ++;
}
}
If (FP! = NULL)
{
Fclose (FP );
}
Return 0;
}