Output to both console and txt file - c

I think this is written in C, honestly don't know how to identify (if someone could give some tips it would be great). When the command rpt dumpvars 1234 is run in the console it returns the variables of machine/node 1234 to the screen. I want the same data output to a variables.txt file. Is there a simple one liner that I can add to do this?
The file is located here.
The portion of the data I am trying to get can be found on lines 7590-7623 as pasted here:
/*
* Display a node's main channel variables from the command line
*/
static int rpt_do_showvars(int fd, int argc, char *argv[])
{
int i,thisRpt = -1;
struct ast_var_t *newvariable;
if (argc != 3) return RESULT_SHOWUSAGE;
for(i = 0; i < nrpts; i++)
{
if(!strcmp(argv[2], rpt_vars[i].name))
{
thisRpt = i;
break;
}
}
if (thisRpt < 0)
{
ast_cli(fd, "Unknown node number %s.\n", argv[2]);
return RESULT_FAILURE;
}
i = 0;
ast_cli(fd,"Variable listing for node %s:\n",argv[2]);
ast_channel_lock(rpt_vars[thisRpt].rxchannel);
AST_LIST_TRAVERSE (&rpt_vars[thisRpt].rxchannel->varshead, newvariable,
entries) {
i++;
ast_cli(fd," %s=%s\n", ast_var_name(newvariable),
ast_var_value(newvariable));
}
ast_channel_unlock(rpt_vars[thisRpt].rxchannel);
ast_cli(fd," -- %d variables\n", i);
return(0);
}

Related

The Code doesn't print the expected output, why?

The following code doesn't behave as expected ..
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
struct dest
{
char filename[20], keyword[20];
bool opened;
FILE * file;
};
void display_data(const struct dest p) {
printf("Keyword: %s, Filename: %s, Used: %s\n", p.keyword, p.filename, p.opened ? "Yes" : "No");
}
int main(int argc, char const *argv[])
{
// declaring variables
float lon, lat;
char info[80];
FILE *reader;
// checking required arguments
if ((argc+1) % 2 || argc < 2) {
fprintf(stderr, "Usage: %s file_to_read file_for_unknown type file type file ...\n", argv[0]);
return 2;
}
// opening the reader
if (!(reader = fopen(argv[1], "r"))) {
fprintf(stderr, "File can't be accessed: %s\n", argv[1]);
return 2;
}
// creating important globals
const short pairs = (argc-3)/2;
struct dest data[pairs];
struct dest other;
strcpy(other.filename, argv[2]);
other.opened = false;
// gathering data
short times = 4;
for(short i = 4; i < argc; i += 2) {
data[i-times].opened = false;
strcpy(data[i-times].keyword, argv[i-1]);
strcpy(data[i-times].filename, argv[i]);
times += 1;
}
// finally, scanning the file ..
struct dest *use_f; // pointer for the wanted destination ..
bool known;
while (fscanf(reader, "%f,%f,%79[^\n]", &lat, &lon, info)) {
// deciding which file to use ..
known = false;
for(short i=0; i < pairs; ++i) {
if (strstr(info, data[i].keyword)) {
known = true;
use_f = &data[i];
}
}
if (!(known)) {
use_f = &other;
}
// checking the file ..
if (!((*use_f).opened)) {
(*use_f).file = fopen((*use_f).filename, "w");
(*use_f).opened = true;
}
// writing to the file ..
fprintf((*use_f).file, "%f,%f,%s\n", lat, lon, info);
}
// closing all data streams, and informing user ..
for (short i=0; i < pairs; ++i) {
display_data(data[i]);
if (data[i].opened) {
fclose(data[i].file);
data[i].opened = false;
}
}
fclose(reader);
fclose(other.file);
return 0;
}
The command used to run it is this ..
./categorize spooky.csv other.csv UFO UFOS.csv # I get no output at all
It seems that the while loop doesn't actually end, which is mysterious, because the file (spooky.csv) is only 11 lines !
30.685163,-68.137207,Type=Yeti
28.304380,-74.575195,Type=UFO
29.132971,-71.136475,Type=Ship
28.343065,-62.753906,Type=Elvis
27.868217,-68.005371,Type=Goatsucker
30.496017,-73.333740,Type=Disappearance
26.224447,-71.477051,Type=UFO
29.401320,-66.027832,Type=Ship
37.879536,-69.477539,Type=Elvis
22.705256,-68.192139,Type=Elvis
27.166695,-87.484131,Type=Elvis
It just keeps writing to other.file, yet I don't know why ..
The program simply doesn't end, can anybody explain things to me ?
From the fscanf() manpage: "The value EOF is returned if an input failure occurs before any conversion (such as an end-of-file) occurs."
Here's a hint... EOF isn't equal to 0. Your while-loop never terminates.

Error with content being read out of file

Hello fellow programmers i am trying to understand what exactly is happening in this area of my code.
Problem: I read some contents into a file , then i am trying to read back the contents out of the file just to make sure its the right contents i had put into the file but it is not giving me the correct output, so i am a little confused here is the code(saved content as binary) :
typedef struct acc
{
int id_no;
int pin;
float bal;
}Acc;
int Crte_acc(FILE *flepss)
{
int i,cnt;
Acc user[1000];
cnt = 1000;
for (i=1;i<1000;i++)
{
cnt+=1;
user[i].id_no = cnt;
user[i].bal=1000;
user[i].pin=0000;
fwrite(&user[i].id_no,sizeof(int),1,flepss);
fwrite(&user[i].pin,sizeof(int),1,flepss);
fwrite(&user[i].bal,sizeof(int),1,flepss);
}
return fclose(flepss);
}
Yea so above is the code that takes a file pointer and a count to keep the id to increase by 1 ( 1001,1002 etc), bal and pin required that i set the var with those digits.So i am wondering whats the problem, this is the code of me displaying the contents.
void DisplyFile()
{
FILE *dfp;
int x;
Acc pruser[1000];
dfp = fopen("Account.dat","rb");
fseek(dfp,0,SEEK_SET);
while (1)
{
if(!feof(dfp))
{
for (x=1;x<1000;x++)
{
fread(&pruser[x].id_no,sizeof(pruser[x].id_no),1,dfp);
fread(&pruser[x].pin,sizeof(pruser[x].pin),1,dfp);
fread(&pruser[x].bal,sizeof(pruser[x].bal),1,dfp);
printf("%d ",pruser[x].id_no);
printf("%d ",pruser[x].pin);
printf("%.2f\n\n",pruser[x].bal);
}
}
else
{
break;
}
}
}
EDIT: By contents coming out wrong i mean , giving me garbage values as to show that my write to file was not saved.
The problem may come from a missing fclose or fopen...
There is almost nothing to do to build something that works.
Three things to check :
-Does a fopen correspond to a fclose ?
-Are opening types similar ? Are both "wb" and "rb" used ?
-Another point is fwrite(&user[i].bal,sizeof(int),1,flepss);...bla is a float. float and int may have the same sizeof, but...It is safer to assume that it is not always the case !
#include <stdio.h>
typedef struct acc
{
int id_no;
int pin;
float bal;
}Acc;
int Crte_acc()
{
FILE *flepss;
int i,cnt;
Acc user[10];
cnt = 1000;
flepss = fopen("Account.dat","wb");
for (i=1;i<10;i++)
{
cnt+=1;
user[i].id_no = cnt;
user[i].bal=10;
user[i].pin=0000;
fwrite(&user[i].id_no,sizeof(int),1,flepss);
fwrite(&user[i].pin,sizeof(int),1,flepss);
fwrite(&user[i].bal,sizeof(float),1,flepss);
}
return fclose(flepss);
}
void DisplyFile()
{
FILE *dfp;
int x;
Acc pruser[10];
dfp = fopen("Account.dat","rb");
fseek(dfp,0,SEEK_SET);
while (1)
{
if(!feof(dfp))
{
for (x=1;x<10;x++)
{
fread(&pruser[x].id_no,sizeof(pruser[x].id_no),1,dfp);
fread(&pruser[x].pin,sizeof(pruser[x].pin),1,dfp);
fread(&pruser[x].bal,sizeof(pruser[x].bal),1,dfp);
printf("%d ",pruser[x].id_no);
printf("%d ",pruser[x].pin);
printf("%.2f\n\n",pruser[x].bal);
}
}
else
{
break;
}
}
fclose(dfp);
}
int main()
{
Crte_acc();
printf("file printed\n");
DisplyFile();
printf("end file read 1\n");
DisplyFile();
printf("end file read 2\n");
return 0;
}
To compile : gcc main.c -o main
Bye,

Execv failing even when command is available

I'm trying to call execv after manually saerching for the program to execute.
In my case,
c is a struct which has args as an array of strings having the arguments passed while receiving input. nargs is the number of arguments.
c->args[0] would contain "ls","cat" etc.
I tried printing the value of the args[0], fullPath etc. in my child process. They all show values like "/bin/ls","/bin/cat" etc. But when I call execv, it returns -1 with an errno of 2, which I understand is the error for "No such file or directory". But I'm sure the file is there because thats what my PathResolver is returning after checking all permissions.
Can anyone point where I might have made a mistake.
//The part happening inside child
char *fullPath = PathResolver(c->args[0],1,&permission);
printf("FullPath: %s -- Permission: %d\n",fullPath,permission);
if(permission==0)
{
fprintf(stderr, "%s: Command not found\n",c->args[0]);
}
else if(permission==-1)
{
fprintf(stderr, "%s: Permission denied\n",c->args[0]);
}
else
{
char* args[c->nargs+1];
int m=0;
for(m=0;m<c->nargs;m++)
{
strcpy(args[m],c->args[m]);
}
args[c->nargs] = NULL;
printf("%d\n",execv(args[0], args));
printf("errno: %d\n",errno);
}
PathResolver function
char* PathResolver(char *command, int ResolverMode, int *Permission)
{
*Permission = 0;
char *returnString;
returnString = malloc((sizeof(char)));
char *strPath = getenv("PATH");
char *del = ":";
char *strToken = strtok(strPath,del);
FILE *f;
while(strToken)
{
char filePath[100];
sprintf(filePath,"%s/%s",strToken,command);
if(access(filePath,F_OK)>=0)
{
if(access(filePath,X_OK)>=0)
{
*Permission = 1;
sprintf(returnString,"%s%s ",returnString,filePath);
if(ResolverMode == 1)
break;
}
else
{
*Permission = -1;
}
}
strToken = strtok(NULL,del);
}
sprintf(returnString,"%s\b",returnString);
return returnString;
}
strcpy(args[m],c->args[m]); is undefined behaviour, because args[m] is not a pointer to valid memory.
The following might be simpler:
char * args[c->nargs + 1];
for (size_t m = 0; m != c->nargs; ++m)
{
args[m] = c->args[m];
}
args[c->nargs] = NULL;
There's no need to copy the strings.
(This may not be your actual problem, but it certainly prevents your program from being correct.)
execv() expects the program name to be prefixed by a full path as 1st parameter.
To have PATH searched instead of providing a path use execvp().
Update:
Also this line
returnString = malloc((sizeof(char)));
does only allocate 1 byte to returnString, which is way to few for how you use returnString.

User entered string run a particular function in c

Guys so I'm working on the web service assignment and I have the server dishing out random stuff and reading the uri but now i want to have the server run a different function depending on what it reads in the uri. I understand that we can do this with function pointers but i'm not exactly sure how to read char* and assign it to a function pointer and have it invoke that function.
Example of what I'm trying to do: http://pastebin.com/FadCVH0h
I could use a switch statement i believe but wondering if there's a better way.
For such a thing, you will need a table that maps char * strings to function pointers. The program segfaults when you assign a function pointer to string because technically, a function pointer is not a string.
Note: the following program is for demonstration purpose only. No bounds checking is involved, and it contains hard-coded values and magic numbers
Now:
void print1()
{
printf("here");
}
void print2()
{
printf("Hello world");
}
struct Table {
char ptr[100];
void (*funcptr)(void)
}table[100] = {
{"here", print1},
{"hw", helloWorld}
};
int main(int argc, char *argv[])
{
int i = 0;
for(i = 0; i < 2; i++){
if(!strcmp(argv[1],table[i].ptr) { table[i].funcptr(); return 0;}
}
return 0;
}
I'm gonna give you a quite simple example, that I think, is useful to understand how good can be functions pointers in C. (If for example you would like to make a shell)
For example if you had a struct like this:
typedef struct s_function_pointer
{
char* cmp_string;
int (*function)(char* line);
} t_function_pointer;
Then, you could set up a t_function_pointer array which you'll browse:
int ls_function(char* line)
{
// do whatever you want with your ls function to parse line
return 0;
}
int echo_function(char* line)
{
// do whatever you want with your echo function to parse line
return 0;
}
void treat_input(t_function_pointer* functions, char* line)
{
int counter;
int builtin_size;
builtin_size = 0;
counter = 0;
while (functions[counter].cmp_string != NULL)
{
builtin_size = strlen(functions[counter].cmp_string);
if (strncmp(functions[counter].cmp_string, line, builtin_size) == 0)
{
if (functions[counter].function(line + builtin_size) < 0)
printf("An error has occured\n");
}
counter = counter + 1;
}
}
int main(void)
{
t_function_pointer functions[] = {{"ls", &ls_function},
{"echo", &echo_function},
{NULL, NULL}};
// Of course i'm not gonna do the input treatment part, but just guess it was here, and you'd call treat_input with each line you receive.
treat_input(functions, "ls -laR");
treat_input(functions, "echo helloworld");
return 0;
}
Hope this helps !

SQLite with Ansi C and xCode

I'm starting from the bottom-up to learn iPad development after 15 years with Cold Fusion. I'm getting comfortable with Ansi C and xCode, but am stumped taking the next step with SQLite.
I've built a database (Airports.sqlite) with razorSQL and installed it in the same directory as main.c where I've also installed the amalgamated sqlite3.h and sqlite3.h files.
Everything compiles OK, but I get the following message when I Run...
Error in select statement select Length from Runways order by Length desc limit 5 [no such table: Runways].
The database definitely has the Runways table in it. Can someone set me straight? Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "weightbalance.h"
sqlite3* db;
int first_row;
int select_callback(void *p_data, int num_fields, char **p_fields, char **p_col_names) {
int i;
int *p_rn = (int*)p_data;
if (first_row) {
first_row = 0;
for(i=0; i < num_fields; i++) {
printf("%20s", p_col_names[i]);
}
printf("\n");
for(i=0; i< num_fields*20; i++) {
printf("=");
}
printf("\n");
}
(*p_rn)++;
for(i=0; i < num_fields; i++) {
printf("%20s", p_fields[i]);
}
printf("\n");
return 0;
}
void select_stmt(const char* stmt) {
char *errmsg;
int ret;
int nrecs = 0;
first_row = 1;
ret = sqlite3_exec(db, stmt, select_callback, &nrecs, &errmsg);
if(ret!=SQLITE_OK) {
printf("Error in select statement %s [%s].\n", stmt, errmsg);
}
else {
printf("\n %d records returned.\n", nrecs);
}
}
void sql_stmt(const char* stmt) {
char *errmsg;
int ret;
ret = sqlite3_exec(db, stmt, 0, 0, &errmsg);
if(ret != SQLITE_OK) {
printf("Error in statement: %s [%s].\n", stmt, errmsg);
}
}
int main() {
sqlite3_open("Airports.sqlite", &db);
if(db == 0) {
printf("Could not open database.");
return 1;
}
printf("\nSelecting Airports with the longest runways.\n\n");
select_stmt("select Length from Runways order by Length desc limit 5");
sqlite3_close(db);
return 0;
}
Most likely, the file "Airports.sqlite" opened in main() is not the one you think it is. Without path information, sqlite3_open() will just open the file in the current working directory.
As a debug step, add "printf(getwd(NULL))" just before your sqlite3_open() statement. Then you'll know whether you're opening your existing database or just creating a new, empty one that is missing your table.
Also, since you're using Xcode, you can just pass the path to your database as a command-line parameter (argv). In Xcode 4, choose Product->Edit Scheme. In the "run" section, add the path to "Arguments Pass On Launch". Then you can just pass argv[1] to your sqlite3_open().

Resources