Convert curl command that attaches file to c - libcurl function - c

Here is the curl command:
curl -X POST \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d #- https://api.clarifai.com/v2/models/aaa03c23b3724a16a56b629203edc62c/outputs << FILEIN
{
"inputs": [
{
"data": {
"image": {
"base64": "$(base64 /home/user/image.png)"
}
}
}
]
}
FILEIN
The question is how can I attach the file on c libcurl code?
Many Thanks,
Ben

Related

Is there a way club two Linux command together in system() function in C?

I wanted to execute who command and cut out the needed info like who | cut -d " " -f 1,21,23 but by using the system() function in c.
I tried doing system("who | cut -d " " -f 1,21,23") which did not work.
The code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ErrorBC -69
int main(int argc, char* argv[]){
if(argc < 2){
printf("No arguments passed\n");
return -69;
}
else{
int i=0;
for(i=1;i<argc;i++){
if((strcmp("kernel",argv[i]))==0){
system("uname -s -r");
}
else if(((strcmp("ulog",argv[i]))==0)){
system("who | cut -d " " -f 1,21,23");
}
else{
printf("%s is not a valid options\n",argv[i]);
}
}
}
}
The output:
c99 test.c
/usr/sahil: ./a.out ulog
Usage: cut {-b <list> [-n] | -c <list> | -f <list> [-d <char>] [-s]} file ...
With "who | cut -d " " -f 1,21,23" you have two strings: "who | cut -d " and " -f 1,21,23". They are concatenated to "who | cut -d -f 1,21,23".
To include double-quotes inside C strings you need to escape them with the backslash: "who | cut -d \" \" -f 1,21,23".

Why is the following shell command working when executed directly in command line, but not working when executed through C program using popen/system?

The command is : ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'
I am running it through adb shell. Basically, I want a list of processes (and certain parameters) which are currently in the run queue. This is working fine if I run it directly through the shell.
However, if I put it in a C program and cross-compile it to run on Android, it's not working. Only ps -c -p is working (I have checked that). But on running this ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R', I get the output :
usage: tr [-cds] SET1 [SET2]
Translate, squeeze, or delete characters from stdin, writing to stdout
-c/-C Take complement of SET1
-d Delete input characters coded SET1
-s Squeeze multiple output characters of SET2 into one character
tr: Needs 1 argument
usage: cut OPTION... [FILE]...
Print selected parts of lines from each FILE to standard output.
-b LIST select only these bytes from LIST.
-c LIST select only these characters from LIST.
-f LIST select only these fields.
-d DELIM use DELIM instead of TAB for field delimiter.
-s do not print lines not containing delimiters.
-n don't split multibyte characters (Ignored).
cut: Needs -fcb
I think the output of ps -c -p is not being conveyed to tr, which doesn't convey it to cut.
Can you please suggest what's the issue?
Here's the code I am using:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 128
int main(int argc,char **argv)
{
char *cmd4 = "ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'";
system(cmd4);
FILE *fp;
char buf[BUFSIZE];
// Another method
if ((fp = popen(cmd4, "r")) == NULL) {
printf("Error opening pipe4!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("cmd 4 running!");
printf("OUTPUT: %s", buf);
}
if(pclose(fp)) {
printf("Command not found or exited with error status4\n");
return -1;
}
return 0;
}
In the shell, you're using the following command:
ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'
In C, you're passing the following to system (and later to popen):
ps -c -p | tr -s | cut -d -f 2,6-10,13 | grep 'R'
See the difference? Quotes need to be escaped in C source code. Also, when you have trouble like this, be sure to output the relevant data so you can see what is actually happening instead of what you planned. A simple puts(cmd4) would have revealed this instantly.

libcurl: my implementation is slower than native curl

I was experimenting with C and libcurl, and noticed that my implementation takes longer than native /usr/bin/curl, while doing a simple HTTPS GET.
Here's my source:
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
/*
#define SKIP_HOSTNAME_VERIFICATION
#define SKIP_PEER_VERIFICATION
*/
int try_url(char *url);
int main(int argc, char **argv){
try_url(argv[1]);
puts("Done");
return 0;
}
int try_url(char *url){
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
#endif
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
res = curl_easy_perform(curl);
if(res != CURLE_OK){
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
Here's the time takes for it to run:
$ time ./a.out "https://dns.google.com/resolve?name=dns.google.com&type=A" 2>/dev/null
{"Status": 0,"TC": false,"RD": true,"RA": true,"AD": false,"CD": false,"Question":[ {"name": "dns.google.com.","type": 1}],"Answer":[ {"name": "dns.google.com.","type": 1,"TTL": 78,"data": "216.58.217.46"}]}Done
real 0m1.038s
user 0m0.746s
sys 0m0.109s
Here's the native curl binary, finishing it in just half the time:
$ time curl -o /dev/null "https://dns.google.com/resolve?name=dns.google.com&type=A" 2>/dev/null
real 0m0.412s
user 0m0.196s
sys 0m0.020s
Could you please point me the right way?
Happens with other urls More info:
$ dpkg -l |egrep "curl|ssl"
ii curl 7.52.1-5+deb9u8 armhf command line tool for transferring data with URL syntax
ii libcurl3:armhf 7.52.1-5+deb9u8 armhf easy-to-use client-side URL transfer library (OpenSSL flavour)
ii libcurl3-gnutls:armhf 7.52.1-5+deb9u9 armhf easy-to-use client-side URL transfer library (GnuTLS flavour)
ii libcurl4-gnutls-dev:armhf 7.52.1-5+deb9u9 armhf development files and documentation for libcurl (GnuTLS flavour)
ii libssl1.0.2:armhf 1.0.2q-1~deb9u1 armhf Secure Sockets Layer toolkit - shared libraries
ii libssl1.1:armhf 1.1.0j-1~deb9u1 armhf Secure Sockets Layer toolkit - shared libraries
ii openssl 1.1.0j-1~deb9u1 armhf Secure Sockets Layer toolkit - cryptographic utility
ldd on my a.out:
$ ldd a.out
linux-vdso.so.1 (0x7eed3000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f65000)
libcurl-gnutls.so.4 => /usr/lib/arm-linux-gnueabihf/libcurl-gnutls.so.4 (0x76eeb000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76dac000)
libnghttp2.so.14 => /usr/lib/arm-linux-gnueabihf/libnghttp2.so.14 (0x76d7e000)
libidn2.so.0 => /usr/lib/arm-linux-gnueabihf/libidn2.so.0 (0x76d4c000)
librtmp.so.1 => /usr/lib/arm-linux-gnueabihf/librtmp.so.1 (0x76d23000)
libssh2.so.1 => /usr/lib/arm-linux-gnueabihf/libssh2.so.1 (0x76cee000)
libpsl.so.5 => /usr/lib/arm-linux-gnueabihf/libpsl.so.5 (0x76cd1000)
libnettle.so.6 => /usr/lib/arm-linux-gnueabihf/libnettle.so.6 (0x76c8a000)
libgnutls.so.30 => /usr/lib/arm-linux-gnueabihf/libgnutls.so.30 (0x76afd000)
libgssapi_krb5.so.2 => /usr/lib/arm-linux-gnueabihf/libgssapi_krb5.so.2 (0x76ab4000)
libkrb5.so.3 => /usr/lib/arm-linux-gnueabihf/libkrb5.so.3 (0x769fd000)
libk5crypto.so.3 => /usr/lib/arm-linux-gnueabihf/libk5crypto.so.3 (0x769be000)
libcom_err.so.2 => /lib/arm-linux-gnueabihf/libcom_err.so.2 (0x769ab000)
liblber-2.4.so.2 => /usr/lib/arm-linux-gnueabihf/liblber-2.4.so.2 (0x7698f000)
libldap_r-2.4.so.2 => /usr/lib/arm-linux-gnueabihf/libldap_r-2.4.so.2 (0x7693a000)
libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0x76913000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x768ea000)
/lib/ld-linux-armhf.so.3 (0x76f7b000)
libunistring.so.0 => /usr/lib/arm-linux-gnueabihf/libunistring.so.0 (0x767db000)
libhogweed.so.4 => /usr/lib/arm-linux-gnueabihf/libhogweed.so.4 (0x7679e000)
libgmp.so.10 => /usr/lib/arm-linux-gnueabihf/libgmp.so.10 (0x7672b000)
libgcrypt.so.20 => /lib/arm-linux-gnueabihf/libgcrypt.so.20 (0x7665a000)
libp11-kit.so.0 => /usr/lib/arm-linux-gnueabihf/libp11-kit.so.0 (0x765fa000)
libidn.so.11 => /lib/arm-linux-gnueabihf/libidn.so.11 (0x765b9000)
libtasn1.so.6 => /usr/lib/arm-linux-gnueabihf/libtasn1.so.6 (0x76599000)
libkrb5support.so.0 => /usr/lib/arm-linux-gnueabihf/libkrb5support.so.0 (0x76580000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x7656d000)
libkeyutils.so.1 => /lib/arm-linux-gnueabihf/libkeyutils.so.1 (0x7655a000)
libresolv.so.2 => /lib/arm-linux-gnueabihf/libresolv.so.2 (0x76535000)
libsasl2.so.2 => /usr/lib/arm-linux-gnueabihf/libsasl2.so.2 (0x7650e000)
libgpg-error.so.0 => /lib/arm-linux-gnueabihf/libgpg-error.so.0 (0x764ee000)
libffi.so.6 => /usr/lib/arm-linux-gnueabihf/libffi.so.6 (0x764d6000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x764a7000)
Update:
Took out libcurl4-gnutls-dev and installed libcurl4-openssl-dev
498 apt-get remove libcurl4-gnutls-dev
499 apt install libcurl4-openssl-dev
It is behaving much better now:
$ time curl -o /dev/null "https://dns.google.com/resolve?name=dns.google.com&type=A" 2>/dev/null
real 0m0.302s
user 0m0.200s
sys 0m0.020s
$ time ./a.out "https://dns.google.com/resolve?name=dns.google.com&type=A" 2>/dev/null
{"Status": 0,"TC": false,"RD": true,"RA": true,"AD": false,"CD": false,"Question":[ {"name": "dns.google.com.","type": 1}],"Answer":[ {"name": "dns.google.com.","type": 1,"TTL": 299,"data": "216.58.217.46"}],"Comment": "Response from 2001:4860:4802:34::a."}Done
real 0m0.294s
user 0m0.196s
sys 0m0.020s

Compile WebAssembly program dependent on external libraries Opus and Faac

1.I git clone opus and faac.
2.second, I am coding:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <opus.h>
#include <faac.h>
void Opus2AacInit() {
int err_code = 0;
unsigned long input_samples = 0;
decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err_code);
if ( err_code < 0 ) {
flag = FALSE;
DebugPrint("%s Opus2Pcm-> opus_decoder_create err_code < 0, err_code:%d\n", ERROR, err_code);
return;
}
enc_handle = faacEncOpen(SAMPLE_RATE, CHANNELS, &input_samples, &max_output_bytes);
if ( enc_handle == NULL ) {
flag = FALSE;
DebugPrint("%s Opus2AacInit-> hEncoder == NULL, failed\n", ERROR);
return;
}
pcm_buffer_size = input_samples * PCM_BIT_SIZE / 8;
DebugPrint("%s Opus2AacInit-> input_samples:%lu, max_output_bytest:%lu, pcm_buffer_size:%d\n", INFO, input_samples, max_output_bytes, pcm_buffer_size);
aac_buffer = (unsigned char *)malloc(max_output_bytes);
pcm_buffer = (unsigned char *)malloc(pcm_buffer_size);
enc_configuration = faacEncGetCurrentConfiguration(enc_handle);
enc_configuration->inputFormat = FAAC_INPUT_16BIT;
aac_ret = faacEncSetConfiguration(enc_handle, enc_configuration);
flag = TRUE;
}
you can see, i am using opus and aac in my project. but that has problem when i complied my project to use webassembly.
emcc ../hello/aac/opus2aac.c -s WASM=1 -s "MODULARIZE=1" -s "EXPORT_NAME='Opus2Aac'" -s "BINARYEN_METHOD='native-wasm'" -s "EXPORTED_FUNCTIONS=['_Opus2AacInit', '_Opus2Aac', '_test']" -o ../hello/aac/opus2aac.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
#include <opus.h>
^~~~~~~~
1 error generated.
ERROR:root:compiler frontend failed to generate LLVM bitcode, halting
so, I do not know how to build two library to my project by using webassembly?
thanks.
You'll need to include the source code and header files for both libopus and faac with the proper locations on your computer, similar to this:
emcc \
-o ../hello/aac/opus2aac.js \
-s WASM=1 -s "MODULARIZE=1" -s "EXPORT_NAME='Opus2Aac'" \
-s "BINARYEN_METHOD='native-wasm'" \
-s "EXPORTED_FUNCTIONS=['_Opus2AacInit', '_Opus2Aac', '_test']" \
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' \
-I "$LIBOPUS_DIR/include" \
-I "$FAAC_DIR/include" \
"$LIBOPUS_DIR" \
"$FAAC_DIR" \
../hello/aac/opus2aac.c
To speed things up during development, I recommend that you compile libopus and facc separately with emcc and then include the compiled *.dylib files into your build command. I did something similar with Opus in this Makefile

Using commands of .exe files in c language

a few months back I wrote a batch (windows batch file .bat) code that fetches some .exe files and use their commands to do different things. e.g encoding audio, video etc...
Now I want the same thing but want to do it in C language.
set var = "Video"ffmpeg -i %var%.mkv -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of %var%-Audio.aac
This code works fine in windows batch file (given that I have specified files in the same folder.)
But now I want to do this via C language. Well I know using
system("ffmpeg -i Video.mkv -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of Video-Audio.aac");
will work for C language, but the drawback is I can't use variable while exploiting ffmpeg's and neroAacEnc's commands / parameters.
So is there anyway to get around it?
(Also, I'm gonna use other .exe files as well like x264.exe and mkvmerge.exe, so i'd appreciate it if someone could tell me how to use external .exe files parameters freely in C language.)
char *var="Video"
char cmd[512];
sprintf(cmd, "ffmpeg -i Video.mkv -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of %s-Audio.aac", var);
system(cmd);
you can make more than 1 variable
char *var="Video"
char *app="ffmpeg";
char cmd[512];
sprintf(cmd, "%s -i Video.mkv -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of %s-Audio.aac", app, var);
system(cmd);
Try this:
char var[50];
char command[256];
sprintf(var,"%s","Video");
sprintf(command,"ffmpeg -i %s.mkv -f wav -| neroAacEnc -ignorelength -lc -q 0.4 -if - -of %s-Audio.aac",var,var);
system(command);
Use snprintf. It is safer alternative to sprintf.
/* Construct command */
#define MAX_CMD_LEN 32
char command[MAX_CMD_LEN];
const char * param1 = "abc";
int param2 = 6;
int len = snprintf(command, MAX_CMD_LEN, "ffmpeg %s %d", param1, param2);
/* Run command if all went well */
if(len > 0 && len < MAX_CMD_LEN) {
system(command); /* Runs 'ffmpeg abc 6' */
}
else {
/* Command didn't fit our buffer */
}

Resources