I have tried googling, and found no solution to my problem. I’m trying to learn how to use libcurl, a c networking library. I tried compiling a program that was automatically generated from curl, and a few examples i found online but nothing happened. I got no errors or logs, the program stopped “sucessfully” but i get no output. I also cant write to the console either while the library is included.

Any help is appreciated.

  • Irelephant@lemm.eeOP
    link
    fedilink
    arrow-up
    1
    ·
    27 days ago

    You’re right, but it doesn’t do anything, no matter what the code is, so I assumed that I needn’t include it. Kinda stupid of me. In any case, here it is:

    /********* Sample code generated by the curl command line tool **********
     * All curl_easy_setopt() options are documented at:
     * https://curl.se/libcurl/c/curl_easy_setopt.html
     ************************************************************************/
    #include <curl/curl.h>
    
    int main(int argc, char *argv[])
    {
      CURLcode ret;
      CURL *hnd;
    
      hnd = curl_easy_init();
      curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
      curl_easy_setopt(hnd, CURLOPT_URL, "https://pastebin.com/api/api_post.php");
      curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
      curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "api_dev_key=MY_API_KEY&api_paste_code=test&api_option=paste");
      curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)81);
      curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/8.9.1");
      curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
      curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
      curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
      curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
    
      /* Here is a list of options the curl code used that cannot get generated
         as source easily. You may choose to either not use them or implement
         them yourself.
    
      CURLOPT_WRITEDATA was set to an object pointer
      CURLOPT_WRITEFUNCTION was set to a function pointer
      CURLOPT_READDATA was set to an object pointer
      CURLOPT_READFUNCTION was set to a function pointer
      CURLOPT_SEEKDATA was set to an object pointer
      CURLOPT_SEEKFUNCTION was set to a function pointer
      CURLOPT_ERRORBUFFER was set to an object pointer
      CURLOPT_STDERR was set to an object pointer
      CURLOPT_HEADERFUNCTION was set to a function pointer
      CURLOPT_HEADERDATA was set to an object pointer
    
      */
    
      ret = curl_easy_perform(hnd);
    
      curl_easy_cleanup(hnd);
      hnd = NULL;
    
      return (int)ret;
    }
    /**** End of sample code ****/
    

    Another piece of code i tried was:

    #include <stdio.h>
    #include <curl/curl.h>
    
    int main(void) {
        CURL *curl;
        CURLcode res;
    
    
        curl_global_init(CURL_GLOBAL_DEFAULT);
        curl = curl_easy_init();
    
        if(curl) {
           
            curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:5000/a");
    
         
            const char *data = "hello!";
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
    
    
            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;
    }
    

    compiled it with gcc test.c -o test.exe -IC:\Users\MY_USERNAME\scoop\apps\curl\current\include -LC:\Users\MY_USERNAME\scoop\apps\curl\current\lib -lcurl but you can replace the paths with wherever the libcurl include directory is (i hope).

    • litchralee@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      3
      ·
      edit-2
      27 days ago

      Unless I’m mistaken, that first example as-written will fetch POST the network resource and then immediately clean up. The fact that CURLOPT_NOPROGRESS is passed means that the typical progress bar for curl in an interactive shell will be suppressed. The comment in the code even says that to make the example do something useful, you’ll have to pass callback pointers, possibly by way of CURLOPT_WRITEFUNCTION or CURLOPT_WRITEDATA.

      From the curl_easy_perform() man page:

      A network transfer moves data to a peer or from a peer. An application tells libcurl how to receive data by setting the CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA options. To tell libcurl what data to send, there are a few more alternatives but two common ones are CURLOPT_READFUNCTION and CURLOPT_POSTFIELDS.

      • Irelephant@lemm.eeOP
        link
        fedilink
        arrow-up
        1
        ·
        27 days ago

        Ah, right.

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <curl/curl.h>
        
        struct MemoryStruct {
            char *memory;
            size_t size;
        };
        
        size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, struct MemoryStruct *userp) {
            size_t realsize = size * nmemb;
            userp->memory = realloc(userp->memory, userp->size + realsize + 1);
            if(userp->memory == NULL) {
                return 0;
            }
            memcpy(&(userp->memory[userp->size]), contents, realsize);
            userp->size += realsize;
            userp->memory[userp->size] = 0;
            return realsize;
        }
        
        int main(int argc, char *argv[]) {
            CURLcode ret;
            CURL *hnd;
            struct MemoryStruct chunk;
        
            chunk.memory = malloc(1);
            chunk.size = 0;
        
            hnd = curl_easy_init();
            if(hnd) {
                curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
                curl_easy_setopt(hnd, CURLOPT_URL, "https://pastebin.com/api/api_post.php");
                curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
                curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "api_dev_key=API_KEY_HERE&api_paste_code=test&api_option=paste");
                curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)81);
                curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/8.9.1");
                curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
                curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
                curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
                curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
                curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
                curl_easy_setopt(hnd, CURLOPT_WRITEDATA, (void *)&chunk);
        
                ret = curl_easy_perform(hnd);
        
                if(ret != CURLE_OK) {
                    fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(ret));
                } else {
                    printf("%s\n", chunk.memory);
                }
        
                curl_easy_cleanup(hnd);
                free(chunk.memory);
            } else {
                fprintf(stderr, "Failed to initialize CURL\n");
            }
        
            return (int)ret;
        }
        

        Finished it, i think. Still does “nothing”

        edit: probably shouldn’t include my api key with it.

        • litchralee@sh.itjust.works
          link
          fedilink
          English
          arrow-up
          2
          ·
          edit-2
          27 days ago

          I’m on mobile so I can’t compile this myself, but can you clarify on what you’re observing? Does “nothing” mean no output to stdout and stderr? Or that you did get an error message but it’s not dispositive as to what libcurl was doing? Presumably the next step would be to validate that the program is executing at all, either with a debugger or printf-style debug statements at all junctures.

          Please include as much detail as you can, since this is now more akin to a bug report.

          EDIT: wait a sec. What exactly is this example code meant to do? The Pastebin API call suggests that this is meant to upload a payload to the web, not pull it down. But CURLOPT_WRITEFUNCTION is for receiving data from a URI. What is your intention with running this example program?

          • Irelephant@lemm.eeOP
            link
            fedilink
            arrow-up
            1
            ·
            27 days ago

            I’m trying to send a post request to Pastebins api to make a paste. This is one of the first programs I have tried to write with libcurl, so its probably wrong.

          • Irelephant@lemm.eeOP
            link
            fedilink
            arrow-up
            1
            ·
            27 days ago

            I have written code before. I just started with C recently. I am expecting it to do literally anything at this point, but for some reason whenever I use the libcurl library literally nothing happens that i can observe.