Problem Statement:
I am trying to upload a file through an HTML form using an HTTP post request and then write it to a file called configuration.xml on my local server. I can only use the stock capabilities of the server, so, as much as I'd love to, I can't use cURL, PHP, Perl, or anything that I'd have to install on the server. What I have tried doing is having the HTML form open a CGI file as the form action and all this CGI file does is run the Bash script with the proper HTML formatting. I would run the Bash script directly from the HTML form, but my research led me to believe that this isn't possible without having to edit .htaccess or other hacky alternatives, which are not roads I want to go down. (If this can be done in a reasonable fashion, please enlighten me!) Regardless, I am able to successfully run the Bash script. I know this because I put a "touch configuration.xml" command in the script and it creates it every time. My script is also able to tell that it is an HTTP Post, as shown by the echoed text in the browser, but then I can't seem to be able to properly read any data from the file. I tried echoing the data as well as redirecting the read data to a file, but nothing appeared in the browser and nothing wrote to the file I specified. This very well may be me not knowing Bash scripting well enough or something silly like that, but I really don't know how to proceed from here.
Code:
UploadToServer.html:
<form action="run_script.cgi" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="Submit">
</form>
run_script.c:
Note: I compile this to a CGI file with the following command: gcc run_script.c -o run_script.cgi
#include <stdlib.h>
#include <stdio.h>
int main() {
system("./test.sh &");
printf("Content-Type: text/html\r\n\r\n");
printf(""); // print blank line for proper HTML header formatting
printf("<html>\n");
printf("</HTML>\n");
}
test.sh:
The non-commented code in the second if statement is from here. The commented code is from here.
#!/bin/bash
touch configuration.xml
if [[ $REQUEST_METHOD = 'POST' ]]; then
echo "this is a post!"
if [ "$CONTENT_LENGTH" -gt 0 ]; then
echo "entered second if statement!"
# read -n $CONTENT_LENGTH POST_DATA <&0
# echo "$CONTENT_LENGTH"
while read line
do eval "echo ${line}"
done
fi
fi
I also tried the approach in the third code block of this post, but didn't get any output. I also looked through this post, but it doesn't seem to grab all the data from the file like I need to. I also tried the approach of just using a CGI file like suggested in this post (_http://blog.purplepixie.org/2013/08/cc-cgi-file-upload/), but, once again, no output. I've been looking through the Apache error log as I try new things and no errors come up.
Anybody have any ideas on what I could possibly be doing wrong? Is there a different approach worth looking into? Any suggestions are greatly appreciated!
I figured out how to do it, with some help from my friends. I ended up doing it all in a CGI script and foregoing the Bash component. While this isn't what I asked for in my original question, it gets the job done for me, which is really what the question was asking.
The following is the C code I'm now using to successfully write the file on the server:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void print_empty_html_page();
int main() {
char * req_method_str = getenv("REQUEST_METHOD");
if (req_method_str != NULL) {
if (strcmp(req_method_str, "POST") == 0) {
// process POST arguments
char * len_str = getenv("CONTENT_LENGTH");
if (len_str != NULL) {
int len = atoi(len_str);
if (len > 0) {
FILE * fp;
fp = fopen("file.xml", "w");
char * postdata = malloc((len + 1) * sizeof(char));
fread(postdata, sizeof(char), len, stdin);
postdata[len] = '\0';
fprintf(fp, "%s\n", postdata);
free(postdata);
fclose(fp);
}
system("sed -e '/Content/d' -e '/[-][-][*][*][*][*][*]/d' -e '/^[s]*$/d' -e '/WebKitFormBoundary/d' -e '/Submit/d' < file.xml > file_trimmed.xml");
system("rm file.xml");
}
}
}
print_empty_html_page();
return 0;
}
void print_empty_html_page() {
// Send the content type, letting the browser know this is HTML
printf("Content-type: text/html\r\n\r\n");
// Header information that prevents browser from caching
printf(
"<META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE, NO-STORE\">\r\n\r\n");
// Top of the page
printf("<html>\n");
printf("<BODY>\n");
// Finish up the page
printf("</BODY></html>\n");
}
Note: This method writes the entire HTTP POST to the file 'file.xml'. The system call to 'sed' is to remove the tags from the HTTP POST that don't correspond to the actual data in the file that was uploaded. If you need to check for additional unwanted lines, just add another -e '/<line_with_expression_to_delete>/d' in that sed call, where line_with_expression_to_delete is the expression you want to match and then delete all lines containing that expression. I couldn't figure out how to delete all the blank lines in the newly uploaded file, even though '/^[s]*$/d' should do that, according to my research. Gonna have to look into that more...
Also note: This method only works for uploading text files. It does not work for other file types, such as JPEGs or OGGs.
Hopefully this helps some other people with the same problem. Let me know if you have any questions.
Related
This script is part of a legacy code that runs to create a GUI interface for editing text files to be used in analysis codes. There is a windows command script that references a ".sed" file which controls the formatting, editing, and help menu for the GUI. I would like to identify the coding language/rules used in these ".sed" files so that I can make a new more complicated input text file with descriptions of inputs.
Ideally, I would like to be able to use this code to create/edit ".csv" files which can be edited in Excel. This would potentially mean needing to avoid the set variable sizes/padding in the #file block of code below.
Any googling attempts to find more about the coding result in unix sed instructions that are not helpful.
UPDATE: I did find an additional exe in the shell folder of the legacy code for "sedwin.exe". When googled this seems to refer to an old "SEDT text editor for MS-DOS".
An example section from a ".sed" file is below:
<code>
#rem( version description information here )
#version(){"2.0"}
%--------------------------------------------------------------------
#file(seal2,native){
title1(A80);
title2(A80);
title3(A80);
r(G10),del(A1),ll(G10),c(G10),lg(G10),dg(G10),ngroov(I10);
ncase(I10),necc(I10),necase(I10),#for(i,1,necase,0){entlos[i](G10)};
#for(i,1,ncase,0){
speed[i](G10),ro[i](G10),nu[i](G10),delp[i](G10);
}
}
#edit(seal2){
#prompted(22,5,"SEAL2 Input Data"){
#help(){
" Code Name Here
"",
"Code description here"
};
#icon("Titles",titles){#titles();}
#icon("Seal Parameters",seal){#seal();}
#icon("Speed, Fluid Parameters",cases){#cases();}
}
}
#titles(){
#prompted(1,7,"Three Title Lines"){
#help(){
"These title lines will appear on the output of",
"the program.",
"",
"They are useful for identifying the output but",
"do not directly affect the results."
};
#datum("",title1,75,"");
#datum("",title2,75,"");
#datum("",title3,75,"");
}
}
#seal(){
#prompted(12,8,"Seal Parameters"){
#help(){
"Descriptions of inputs in this window.",
};
#datum("Shaft Radius (in)",r,15,"0.");
#float_check("Must be > 0.0","(%g)>0.");
#datum("Land Length (in)",ll,15,"0.");
#float_check("Must be > 0.0","(%g)>0.");
#datum("Seal Radial Clearance (in)",c,15,"0.");
#float_check("Must be > 0.0","(%g)>0.");
#datum("Groove Length (in)",lg,15,"0.");
#float_check("Must be >= 0.0","(%g)>=0.");
#datum("Groove Depth (in)",dg,15,"0.");
#float_check("Must be >= 0.0","(%g)>=0.");
#datum("Number of Grooves (0=plain seal)",ngroov,15,"0");
#int_check("Must be >= 0","(%d)>=0");
#datum("Number of Eccentricities",necc,15,"1");
#int_check("Must be between 1 and 10","(%d)>0&&(%d)<11");
#icon("Entrance Loss Cases",losses){#losses();}
}
}
#new_file(seal2){
file_type=seal2;
unit_type=native;
titles=New;
title1=;
title2=;
title3="(SEAL2 Data File)";
del=",";
seal=New;
ll=0.0;
r=0.0;
c=0.0;
lg=0.0;
dg=0.0;
ngroov=0;
losses=New;
necc=1;
necase=1;
entlos[1...necase]=0.1;
cases=New;
ncase=1;
speed[1...ncase]=0.0;
delp[1...ncase]=0.0;
nu[1...ncase]=0.0;
ro[1...ncase]=0.0;
}
</code>
I just want to preface this by saying I am an absolute noob to shell script, so stick with me here.
Essentially, I am trying to combine lines of text from separate test files (one line from HC_01_MNoFraming.txt added at the end of the corresponding line from HC_01_Gist.txt) into a single line of text on a newly created text file called HC_01_MGNoFraming.txt. This combination of the lines of text would occur for each of the four lines of text in each text file. Below is an example:
HC_01_Gist.txt
12.0130754383 33.0026698754 117.01282238700001 182.01823507400002 201.005570202 220.010026843 352.023495725 478.012859369 518.0072172580001
12.012680624100001 56.0118834624 144.026174161 167.018345335 228.002317522 247.00666698400002 356.027611312 434.014129075 478.013307259
56.01133045 142.00709709999998 207.0121417 331.01635039999996 350.0040858 369.0084907 390.01512310000004 409.0028586 430.0265601 512.0175128999999 556.0159299
12.012615221199999 176.01120546400003 199.00347731 243.019245908 430.00998814900004 472.02324678400004 495.01541966900004
HC_01_MNoFraming
262.006565969 283.013202477 375.015624781 541.016055549
33.019710919299996 497.017719727 537.0287543219999
121.0167582 226.0165682
75.01583263170001 113.024949998 262.023691934 386.010783941 537.011983108
HC_01_MGNoFraming.txt
12.0130754383 33.0026698754 117.01282238700001 182.01823507400002 201.005570202 220.010026843 352.023495725 478.012859369 518.0072172580001 262.006565969 283.013202477 375.015624781 541.016055549
12.012680624100001 56.0118834624 144.026174161 167.018345335 228.002317522 247.00666698400002 356.027611312 434.014129075 478.013307259 33.019710919299996 497.017719727 537.0287543219999
56.01133045 142.00709709999998 207.0121417 331.01635039999996 350.0040858 369.0084907 390.01512310000004 409.0028586 430.0265601 512.0175128999999 556.0159299 121.0167582 226.0165682
12.012615221199999 176.01120546400003 199.00347731 243.019245908 430.00998814900004 472.02324678400004 495.01541966900004 75.01583263170001 113.024949998 262.023691934 386.010783941 537.011983108
I tried several things but the simplest solution I could find online was just using the paste command like this:
#(A) First Timing File = Timing File you Want to Be in Front
A=HC_01_Gist.txt
#(B) Second Timing File Timing File you Want to Be in Back
B=HC_01_MNoFraming.txt
#(C) Output Timing File Name C=HC_01_MGNoFraming.txt
#------------------------------------------------------------
paste $B $A
paste $B $A >$C
Looking at the terminal output, this is what this code gives:
262.006512.0130754383 33.0026698754 117.01282238700001 182.01823507400002 201.005570202 220.010026843 352.023495725 478.012859369 518.0072172580001
33.0197112.012680624100001 56.0118834624 144.026174161 167.018345335 228.002317522 247.00666698400002 356.027611312 434.014129075 478.013307259
121.016756.01133045 142.00709709999998 207.0121417 331.01635039999996 350.0040858 369.0084907 390.01512310000004 409.0028586 430.0265601 512.0175128999999 556.0159299
75.0158312.012615221199999 176.01120546400003 199.00347731 243.019245908 430.00998814900004 472.02324678400004 495.01541966900004
It almost looks like in terminal that the paste command starts working but then after the first data point of HC_01_MNoFraming, the paste jumbles up the text and then resumes with the second data point of HC_01_Gist.txt.
Looking at the HC_01_MGNoFraming.txt file that the code creates:
262.006565969 283.013202477 375.015624781 541.016055549
12.0130754383 33.0026698754 117.01282238700001 182.01823507400002 201.005570202 220.010026843 352.023495725 478.012859369 518.0072172580001
33.019710919299996 497.017719727 537.0287543219999
12.012680624100001 56.0118834624 144.026174161 167.018345335 228.002317522 247.00666698400002 356.027611312 434.014129075 478.013307259
121.0167582 226.0165682
56.01133045 142.00709709999998 207.0121417 331.01635039999996 350.0040858 369.0084907 390.01512310000004 409.0028586 430.0265601 512.0175128999999 556.0159299
75.01583263170001 113.024949998 262.023691934 386.010783941 537.011983108
12.012615221199999 176.01120546400003 199.00347731 243.019245908 430.00998814900004 472.02324678400004 495.01541966900004
I'm wondering about two things:
1)How can I fix the output .txt file to have the data points in-line 2) how can I ensure that the data points for HC_01_Gist.txt go before the data points for HC_01_MNoFraming.
Thanks and I'd be more than happy to clarify my problem and answer any questions you have.
I have a korn shell script which will pass 4 parameters to a Pro*C file
The syntax of the korn shell script are below:
### $command_dir/proc_file_name / $deptid $txdate $pid
### I hardcode the values for testing
$command_dir/proc_file_name / 701 20170109 201701094444001
The syntax of the Pro*C file:
....
main(argc, argv)
int argc
char *argv[];
username.len=strlen(argv[1]);
strncpy((char*)username.arr, argv[1],username.len);
username.arr[username.len]='\0';
deptid.len=strlen(argv[1]);
strncpy((char*)deptid.arr, argv[1],deptid.len);
deptid.arr[deptid.len]='\0';
txdate.len=strlen(argv[1]);
strncpy((char*)txdate.arr, argv[1],txdate.len);
txdate.arr[txdate.len]='\0';
pid=atoi(argv[4]);
printf("\n%s\n", username);
printf("\n%d\n", deptid);
printf("\n%d\n", txdate);
printf("\n%d\n", pid);
....
I found that the values of the parameters were not I put.
Please help...
Many Many thanks
You are using the same array index of 1 for username, deptid, and txdate. Correct that and you would be good.
Accessing argv[1] etc., without checking argc isn't a good practice. When invoked without arguments, your code will result in a core dump.
Also, I don't think your code has the right syntax. Can you please paste the code that compiles?
i want to save the output pdf file to public folder my method is
public function qrSVG()
{
$qrCodes = ['4659284fff','465928447','465928447','613271980','484016586','aaaaabbbbbccccc'];
$id = ['201596400-1','201596400-2','201596400-3','831070646','493130428','aaaaabbbb'];
PDF::SetTitle('qrcodes\test');
$i=0;
foreach(array_chunk($qrCodes, 2) as $qrCodee)
{
PDF::AddPage();
$m = 55;
$n = 30;
foreach($qrCodee as $qr)
{
QrCode::size(400);
QrCode::margin(3);
QrCode::errorCorrection('H');
QrCode::encoding('UTF-8');
QrCode::backgroundColor(255,255,255);
QrCode::color(0,0,0);
QrCode::imageTitle($id[$i]);
$svg = QrCode::generate($qr);
PDF::ImageSVG('#'.$svg, $x=$m, $y=$n, $w='100', $h='100', $link='', $align='', $palign='', $border=1, $fitonpage=false);
$i++;
$n = 150;
}
}
ob_clean();
PDF::Output('qrcodes\test.pdf');}
this code generate and open the file put don't save it when i replace the last line in my code with PDF::Output('qrcodes\test.pdf', 'F');
when i put any option with PDF::Output there is an error with F and D options the error when use F is
ErrorException in tcpdf_static.php line 2440:
fopen(): remote host file access not supported, file://qrcodes\test.pdf
and when i replace the last line with
PDF::Output($_SERVER['DOCUMENT_ROOT'] . 'qrcodes\test.pdf', 'F');
the error is
ErrorException in tcpdf.php line 2793:
Undefined property: Elibyy\TCPDF\Pdf::$h
The main reason you're getting the error about remote host file access not supported is because you need to provide the full path in the file name that you provide to the Output() method. Yeah, it's a bit annoying and it catches me out all the time!
I can't comment on the second error you're getting because I cannot get your code to run (missing methods in QrCode class). What version are you using? Also, why are you trying to create an SVG for the QR code and then adding that to the PDF? Instead of taking that approach, I would highly recommend following the approach illustrated in this example:
https://github.com/tecnickcom/TCPDF/blob/master/examples/example_050.php
As you will see in the example, you should create an instance of the TCPDF class and then work with that instance, rather than calling the static methods.
I am trying to loop over two series of variables and make them with R statistical software to get the correlation results.
I got confused why the bigger loop (on mica_headers) doesn't take place while the inner loop finishes each time.
#!/bin/sh
#set -e
micaHeaderList="tot_instruction ILP32 ILP64 ILP128 ILP256 total_ins_count_for_hpc_alignment totInstruction mem-read mem-write control-flow arithmetic floating-point stack shift string sse other nop InstrFootprint64 InstrFootprint4k DataFootprint64 DataFootprint4k mem_access memReuseDist0-2 memReuseDist2-4 memReuseDist4-8 memReuseDist8-16 memReuseDist16-32 memReuseDist32-64 memReuseDist64-128 memReuseDist128-256 memReuseDist256-512 memReuseDist512-1k memReuseDist1k-2k memReuseDist2k-4k memReuseDist4k-8k memReuseDist8k-16k memReuseDist16k-32k memReuseDist32k-64k memReuseDist64k-128k memReuseDist128k-256k memReuseDist256k-512k memReuseDist512k-00 GAg_mispred_cnt_4bits PAg_mispred_cnt_4bits GAs_mispred_cnt_4bits PAs_mispred_cnt_4bits GAg_mispred_cnt_8bits PAg_mispred_cnt_8bits GAs_mispred_cnt_8bits PAs_mispred_cnt_8bits GAg_mispred_cnt_12bits PAg_mispred_cnt_12bits GAs_mispred_cnt_12bits PAs_mispred_cnt_12bits total_brCount total_transactionCount total_takenCount total_num_ops instr_reg_cnt total_reg_use_cnt total_reg_age reg_age_cnt_1 reg_age_cnt_2 reg_age_cnt_4 reg_age_cnt_8 reg_age_cnt_16 reg_age_cnt_32 reg_age_cnt_64 mem_read_cnt mem_read_local_stride_0 mem_read_local_stride_8 mem_read_local_stride_64 mem_read_local_stride_512 mem_read_local_stride_4096 mem_read_local_stride_32768 mem_read_local_stride_262144 mem_read_global_stride_0 mem_read_global_stride_8 mem_read_global_stride_64 mem_read_global_stride_512 mem_read_global_stride_4096 mem_read_global_stride_32768 mem_read_global_stride_262144 mem_write_cnt mem_write_local_stride_0 mem_write_local_stride_8 mem_write_local_stride_64 mem_write_local_stride_512 mem_write_local_stride_4096 mem_write_local_stride_32768 mem_write_local_stride_262144 mem_write_global_stride_0 mem_write_global_stride_8 mem_write_global_stride_64 mem_write_global_stride_512 mem_write_global_stride_4096 mem_write_global_stride_32768 mem_write_global_stride_262144"
mhToBeReplaced="ILP32"
compilerOptionList="funsafe_math_optimizations fno_guess_branch_probability fno_ivopts fno_tree_loop_optimize fno_inline_functions funroll_all_loops fno_omit_frame_pointer falign_jumps fselective_scheduling fno_inline_small_functions fno_tree_pre ftracer fno_move_loop_invariants"
coToBeReplaced="fno_guess_branch_probability"
for mica_header in $micaHeaderList
do
for compiler_option in $compilerOptionList
do
echo "Calculating $compiler_option correlation for $mica_header"
sed -i "s/$coToBeReplaced/$compiler_option/g" r.scr
coToBeReplaced=$compiler_option
make
done
sed -i "s/$mhToBeReplaced/$mica_header/g" r.scr
mhToBeReplaced=$mica_header
done
Edited: Generally, in order to avoid inconsistency between the values of iterations and source file, how could I be able to link these two together from different files. i.e. micaHeaderList with the headers inside the ALL.scv file ?
In the script there is a mistake which echoes a value of $mica_header which will be substituted only for make calls in the next outer loop run. This is caused by the second sed being run only after make. It should have been called before the inner loop. Could not this cause the confusion?
Also instead of replacing one value of a parameter for another it is better to create a template of r.src file with placeholders for the parameters to be changed. This way we can be sure that for some values of the parameters there could not be conflicts with the search patterns and that a typo will not prevent substitution.
Below is an improved script with considerably simpler code. The part inside if test "$Test" = 1 is just a testing code activated by Test=1. For this script just create a template for r.scr named r.scr.template and put the placeholders %%MicaHeader%% and %%CompilerOption%% instead of the parameters which should be replaced. For the first test there is a shorter list of parameters.
#!/bin/sh
micaHeaderList="tot_instruction ILP32 ILP64"
mhToBeReplaced=%%MicaHeader%%
compilerOptionList="funsafe_math_optimizations fno_guess_branch_probability fno_ivopts fno_tree_loop_optimize"
coToBeReplaced=%%CompilerOption%%
TemplateFile=r.scr.template
OutputFile=r.scr
Test=1
if test "$Test" = 1
then
TemplateFile="${TemplateFile}-test"
echo "$coToBeReplaced $mhToBeReplaced" >"$TemplateFile"
make ()
{
echo -n ">>> make: "
cat "$OutputFile"
}
fi
for mica_header in $micaHeaderList
do
for compiler_option in $compilerOptionList
do
echo "Calculating $compiler_option correlation for $mica_header"
sed "s/$mhToBeReplaced/$mica_header/g;s/$coToBeReplaced/$compiler_option/g" "$TemplateFile" >"$OutputFile"
make
done
done
If the problem still persists:
Check the generated r.src files.
Check if the make script really uses the substituted parameters from r.src.