I just want to fetch a webpage(its HTML code,if its like www.example.com/example.html) into a text file using C. Is it possible using any library study or anything?
I am really getting lost into "maybe i should learn" PHP or python or something and then use command line invocation of these scripts using system() or exec(). Whats the best way to do so?
My Exact current need is to fetch http://livechat.rediff.com/sports/score/score.txt, which by chance happened to be a .txt file.
use curl or libcurl. It will fetch a webpage for you and you can do whatever you like with it.
As Toby already mentioned, libcurl is probably your best bet. Here is an actual program demonstrating how retrieve a webpage using the libcurl-easy interface:
#include <stdio.h>
#include <curl/curl.h>
int main(int argc, char *argv[]) {
CURL *curl;
CURLcode curl_result;
const char *site;
if (argc != 2) {
fprintf(stderr, "Usage: %s site\n", argv[0]);
return 1;
}
site = argv[1];
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, site);
curl_result = curl_easy_perform(curl);
if(curl_result != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(curl_result));
}
curl_easy_cleanup(curl);
}
else {
fprintf(stderr, "Failed to initialize curl\n");
return 1;
}
return 0;
}
The program takes one argument, the name of the site to retrieve. When compiled with gcc curltest.c -lcurl -o curltest and run as curltest http://livechat.rediff.com/sports/score/score.txt, outputs the following:
l1=England vs South Africa
l2=England
interval=1
message=England 16-2 (13)
tagline=J Trott(6) I Bell(4)*
date=19 August, 2012
ver=19
Related
Hello and Happy new Year ,
I have to accept juste txt files in my C programme ,
I don't have any idea to how to made it .. any ideas?
And I don't know if text file contain Header or something which characterize it..
PS: I'm using Ubuntu so file extension is not seen.
Thank you
In a Linux environment, I would personally go with libmagic, which is the core of the utility program file. The purpose of this library is to do exactly what you are trying to accomplish: identify the type of a file based on it content.
Example usage would look like this.
/* identify.c */
#define _POSIX_SOURCE /* required for fileno() */
#include <magic.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
const char *description;
magic_t cookie;
FILE *fp;
fp = fopen("example.txt", "r");
if(fp == NULL) {
fprintf(stderr, "error: cannot open file\n");
exit(EXIT_FAILURE);
}
cookie = magic_open(MAGIC_NONE);
if(cookie == NULL) {
fprintf(stderr, "error: cannot initialize library\n");
fclose(fp);
exit(EXIT_FAILURE);
}
if( magic_load(cookie, NULL) != 0 ) {
fprintf(stderr, "error: cannot load database : %s\n",
magic_error(cookie));
magic_close(cookie);
fclose(fp);
exit(EXIT_FAILURE);
}
description = magic_descriptor(cookie, fileno(fp));
printf("%s\n", description);
magic_close(cookie);
fclose(fp);
return EXIT_SUCCESS;
}
Name this source file identify.c, create a text file name example.txt with some content in the same directory, and compile with:
gcc -Wall -std=c99 -pedantic -lmagic -o identify identify.c
Then run it.
./identify
And you get something like this printed:
UTF-8 Unicode text
This library can be used in a few different ways, so you should probably have a look at the man page. For example, you can get a MIME type instead of a description like the one above.
The file package of which libmagic is a part is probably already installed on your machine. However, if you are using a distribution such as RHEL of CentOS that splits development headers into a separate package, make sure you have file-devel installed.
I'm designing a pair of c programs that uses basic stream sockets to communicate between two programs, similar to a server-client interaction. Most of the programs seem to work fine, but the client end of the system keeps reporting an error that I can't quite work out.
The client program, once compiled, is executed using a command line argument, which as I understand is supposed to be the name of the server program. However, every time I run the following line
./client server
I get an error that only gets reported in the event that argv[1] is null. Here's the code from string_client.c:
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
printf("%s", argv[1]);
exit(1);
}
server is just the executable file from string_server.c, which is supposed to wait for an incoming request from the client and receive input from the client program(and works as far as that, as far as I can tell). I'm not sure about the gethostbyname method, but as that code was provided, I haven't questioned it yet.
Also, whenever I try printing out argv[1], it comes out as "la"... not sure what's happening there. What's going on with the command line? am I just using the wrong argument?
Here you go:
#include <stdio.h>
#include <netdb.h>
extern int h_errno;
int main(int argc, char **argv)
{
struct hostent *he;
if(argc < 2)
{
printf("usage: %s hostname\n", argv[0]);
return 255;
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
printf("%s", argv[1]);
return 1;
}
printf("%s resolved to %u.%u.%u.%u\n", argv[1],
(unsigned char)(he->h_addr_list[0][0]),
(unsigned char)(he->h_addr_list[0][1]),
(unsigned char)(he->h_addr_list[0][2]),
(unsigned char)(he->h_addr_list[0][3]));
return 0;
}
It works now:
$ gcc -Wall -o gethost gethost.c
$ ./gethost
usage: ./gethost hostname
$ ./gethost google.com
google.com resolved to 173.194.40.196
$ ./gethost localhost
localhost resolved to 127.0.0.1
I'm trying to connect to a MariaDB database in a C script and I can't find the necessary documentation. I installed libmariadbclient-dev, but I couldn't find any accompanying documentation such as a man page. There's a basic description and limited documentation here, but the documentation only includes descriptions of functions. The fact is, despite having scoured all sorts of Google results, I don't even know what to import to get this to work, much less how to use it. Is there any guide or documentation on how to use a MariaDB database in C?
The MariaDB Client Library for C has exactly the same API as the MySQL
Connector/C for MySQL 5.5
Here it is: http://dev.mysql.com/doc/refman/5.5/en/c-api-function-overview.html
Another one:
http://zetcode.com/db/mysqlc/
You can compile a minimal test like
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
MYSQL *con = mysql_init(NULL);
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
if (mysql_real_connect(con, "localhost", "root", "root_pswd",
NULL, 0, NULL, 0) == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
if (mysql_query(con, "CREATE DATABASE testdb"))
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
mysql_close(con);
exit(0);
}
using
gcc -o mysql-test mysql-test.c $(mysql_config --libs)
I'm having trouble writing a C program that displays a command prompt (no problem here) which allows the user to enter unix commands & then displays the results. I've tried many things but I only started programming a year ago and haven't gone anywhere besides displaying the command prompt; I need help on how to accept unix commands + display their results.
My only constraint is that instead of the user providing an absolute path, I need my program to search the directories specified in the path environment variable and find the location of the command's executable. I don't understand how to do this either but searching online has told me this would be best using "getenv() to access the OS PATH variable and prefix the user-supplied command appropriately". Can anyone help me out here? Thanks for your assistance in advance.
Try popen(), which can be found here in the manpages.
Check this out:
#include <stdio.h>
#include <stdlib.h>
void write_netstat(FILE * stream)
{
FILE * outfile;
outfile = fopen("output.txt","w");
char line[128];
if(!ferror(stream))
{
while(fgets(line, sizeof(line), stream) != NULL)
{
fputs(line, outfile);
printf("%s", line);
}
fclose(outfile);
}
else
{
fprintf(stderr, "Output to stream failed.n");
exit(EXIT_FAILURE);
}
}
int main(void)
{
FILE * output;
output = popen("netstat", "r");
if(!output)
{
fprintf(stderr, "incorrect params or too many files.n");
return EXIT_FAILURE;
}
write_netstat(output);
if(pclose(output) != 0)
{
fprintf(stderr, "Could not run 'netstat' or other error.n");
}
return EXIT_SUCCESS;
}
This prints a netstat to a file. You can do this for all commands. It uses popen(). I wrote it because I needed a log of a netstat.
I want to get the value of kernel.shmmax in C code (which I query on centos5.0, centos6.0 and ubuntu10.04 using the shell command "$ sysctl -q kernel.shmmax").
I used the following code to find it:
#include <sys/sysctl.h>
const int SHM_ERROR=1;
main(){
int name[] = {KERN_SHMMAX};
int namelen = 1;
int oldval[1];
size_t oldlen = sizeof(oldval);
int rv = sysctl(name, namelen, (void*) oldval, &oldlen, NULL, 0);
if (rv!=0) {
fprintf(stderr, "while quering for shared memory size, sysctl returned error: %s\n", strerror(errno));
return SHM_ERROR;
}
else{
return 0;
}
}
After running the code above I get the following error:
while quering for shared memory size, sysctl returned error: Not a directory
I am clueless about why I am getting this error. I googled for it and found there is some issue with the paths into which library tries to look into.
I tried running the above code with GDB but the code doesn't steps into the function sysctl, otherwise I could have provided you more information.
Data point:
I am easily able to set and get kernel.shmmax from command line on all the operating systems mentioned using the following commands:
$ sysctl -q kernel.shmmax
$ sysctl -w kernel.shmmax=1000000000
Thanks
You shouldn't be calling sysctl from userspace code. From the man page:
Glibc does not provide a wrapper for this system call; call it using
syscall(2).
Or rather... don't call it: use of this system call has long been
discouraged, and it is so unloved that it is likely to disappear in a
future kernel version. Remove it from your programs now; use the
/proc/sys interface instead.
So give this a shot instead:
#include <stdio.h>
#define SHMMAX_SYS_FILE "/proc/sys/kernel/shmmax"
int main(int argc, char **argv)
{
unsigned int shmmax;
FILE *f = fopen(SHMMAX_SYS_FILE, "r");
if (!f) {
fprintf(stderr, "Failed to open file: `%s'\n", SHMMAX_SYS_FILE);
return 1;
}
if (fscanf(f, "%u", &shmmax) != 1) {
fprintf(stderr, "Failed to read shmmax from file: `%s'\n", SHMMAX_SYS_FILE);
fclose(f);
return 1;
}
fclose(f);
printf("shmmax: %u\n", shmmax);
return 0;
}
I install strace and see that sysctl looks at /proc/sys/kernel/shmmax with open() call instead of _sysctl() call or syscall() call.