Add an option under a specific section using UCI's C API - c

How can I add a NEW option under a specific section in an UCI config file? I would like to achieve that programmatically using the C API. Can someone put an example here ?

#include <uci.h>
#include <stdio.h>
int main() {
uci_context* ctx = uci_alloc_context();
if (!ctx) {
printf("failed to alloc uci ctx\n");
return 1;
}
uci_ptr config;
char section_name[] = "your_package.your_section";
if (uci_lookup_ptr(ctx, &config, section_name, true) != UCI_OK || !config.s) {
printf("failed to find the specified section\n");
return 1;
}
config.option = "new_option_name";
config.value = "new_option_value";
if (uci_set(ctx, &config) != UCI_OK) {
printf("failed to set new option\n");
return 1;
}
if (uci_commit(ctx, &config.p, false) != UCI_OK) {
printf("failed to commit changes\n");
return 1;
}
return 0;
}

Related

How to test if a file is open/closed in different functions in C

I need to write separate functions for opening/closing the file and working with it. Was recommended to not use global variables in it.
I have a function where I need to open the file and print what's in it(open_file), a second to work with the data in it(do_stuff_in_file), and a third to only close the file and exit the program(close_file).
When I try to call do_stuff_in_file or close_file the program just crashes.
I know I'm supposed to use pointers, but I just can't get it right and I don't know where's the mistake.
int open_file(FILE **fr) {
if ((fr = fopen("soldcars.txt", "r")) == NULL) {
printf("File was not opened\n");
return 1;
}
else {
char testchar;
while ((testchar = fgetc(fr)) != EOF) {
ungetc(testchar, fr);
//just printing whats in the file
}
}
return 0;
}
int do_stuff_in_file(FILE **fr, int date) {
if (fr==NULL) {
printf("File not open yet\n");
return 1;
}
else{ fseek(fr, 0, SEEK_SET); } //doing stuff
return 0;
}
int close_file(FILE **fr) {
if (fr==NULL) {
printf("It was not even open yet\n");
return 1;
}
else{
if (fclose(fr) == EOF) {
printf("File was not successfully closed");
return 1;
}
else{
printf("Adios");
exit(1);
}
}
}
int main() {
char input;
int date;
FILE* fr;
fr = NULL;
while ((input = getchar()) != 'c') {
if (input == 'o') open_file(&fr);
else if (input == 'd') {
scanf("%d", &date);
do_stuff_in_file(&fr, date);
}
}
if (input == 'c') {
close_file(&fr);
}
return 0;
}
You need to dereference properly. eg
int open_file(FILE **fr) {
if ((*fr = fopen("soldcars.txt", "r")) == NULL) {
perror( "soldcars.txt" );
return 1;
}
Note *fr = open instead of fr = open. And, in that function, always use *fr, as in fgetc(*fr) vice fgetc(fr). Similarly in the other functions. Because fr is not a FILE *, but *fr is.

How to silent the MP3 decoding process

I am learning ffmpeg and I made a MP3 decoder but when I am executing it , some kind of information is printing on my terminal but I don't want it. So how to silent it ?
Here is code (full code)
/* FFmpeg Usage Example
* Date : 28 July 2019
*/
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <assert.h>
int decode_packet(AVCodecContext*, AVPacket*, AVFrame*);
int main(void) {
AVFormatContext *pFormatContext = avformat_alloc_context();
AVCodecParameters *pCodecParameters = NULL;
if(avformat_open_input(&pFormatContext,"song.mp3",NULL,NULL)!=0) {
fprintf(stderr,"Could not open file\n");
return -1;
}
if(avformat_find_stream_info(pFormatContext,NULL)<0) {
fprintf(stderr,"Could not find stream\n");
return -1;
}
size_t stream_index = 0;
for(;stream_index<pFormatContext->nb_streams;stream_index++) {
if(pFormatContext->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
pCodecParameters = pFormatContext->streams[stream_index]->codecpar;
}
break;
}
if(stream_index == -1) {
fprintf(stderr,"could not retrive stream info from file\n");
return -1;
}
AVStream *stream = pFormatContext->streams[stream_index];
pCodecParameters = stream->codecpar;
AVCodec *cdc = avcodec_find_decoder(pCodecParameters->codec_id);
AVCodecContext *cdc_ctx = avcodec_alloc_context3(cdc);
assert(pCodecParameters);
if(avcodec_parameters_to_context(cdc_ctx,pCodecParameters) < 0) {
fprintf(stderr,"Can't copy params to codec context\n");
return -1;
}
if(avcodec_open2(cdc_ctx,cdc,NULL) < 0) {
fprintf(stderr,"Failed to open decoder for stream\n");
return -1;
}
AVFrame *frame = av_frame_alloc();
if(!frame) {
fprintf(stderr,"could not allocate memory for frame\n");
return -1;
}
AVPacket *packet = av_packet_alloc();
// av_init_packet(&packet);
if(!packet) {
fprintf(stderr,"could not allocate memory for packet");
return -1;
}
packet->data=NULL;
packet->size=0;
// lets read the packets
while(av_read_frame(pFormatContext,packet) >= 0) {
if(packet->stream_index==stream_index) {
int response = 0 ;
response = decode_packet(cdc_ctx,packet,frame);
if(response < 0)
continue;
}
av_packet_unref(packet);
}
return 0;
}
int decode_packet(AVCodecContext *cdc_ctx , AVPacket *pkt, AVFrame *frm) {
int response = avcodec_send_packet(cdc_ctx,pkt);
if(response < 0)
return response;
while(response >= 0) {
response = avcodec_receive_frame(cdc_ctx,frm);
if(response == AVERROR(EAGAIN) || response == AVERROR_EOF)
return -1;
else if(response < 0)
return response;
}
return 0;
}
Expected behaviour : nothing should be printed on screen
Actual behaviour : some kind of logs are printing automatically
Here is output logs ( some of them )
[mp3float # 0x75172e7400] overread, skip -6 enddists: -5 -5
[mp3float # 0x75172e7400] overread, skip -7 enddists: -6 -6
[mp3float # 0x75172e7400] overread, skip -6 enddists: -5 -5
[mp3float # 0x75172e7400] overread, skip -6 enddists: -4 -4
Set the log level to AV_LOG_QUIET. The function prototypes are in libavutil/log.h

UCI C API - How to set multiple options by running a single program only once

I want to set multiple options at the same time using UCI C API.
I tried using below code but this sets only one option at a time.
But how to set multiple options and sections at the same time?
#include <uci.h>
#include <stdio.h>
int main() {
uci_context* ctx = uci_alloc_context();
if (!ctx) {
printf("failed to alloc uci ctx\n");
return 1;
}
uci_ptr config;
char section_name[] = "your_package.your_section";
if (uci_lookup_ptr(ctx, &config, section_name, true) != UCI_OK || !config.s) {
printf("failed to find the specified section\n");
return 1;
}
config.option = "new_option_name";
config.value = "new_option_value";
if (uci_set(ctx, &config) != UCI_OK) {
printf("failed to set new option\n");
return 1;
}
if (uci_commit(ctx, &config.p, false) != UCI_OK) {
printf("failed to commit changes\n");
return 1;
}
return 0;
}

Access violation when getting network adapters with GetAdaptersAddresses in C

I don't know if the code from https://learn.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses is wrong but when I try to use it in my C project I keep getting the infamous
Access violation reading location 0xFFFFFFFFFFFFFFFF
I have tried increasing the buffer size but nothing seems to fix it. I think this happens after the first adapter is passed through the loop.
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <winsock2.h>
#include <iptypes.h>
#include <iphlpapi.h>
#include <windows.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
FILE* fLog = NULL;
void netinfo() {
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
DWORD dwRetVal = 0;
ULONG outBufLen = 15000;
ULONG iter = 0;
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));
wchar_t netAddressLog[256];
if (dwRetVal == NO_ERROR && pAddresses != NULL) {
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
// this is where the debugger stops !!!
swprintf(netAddressLog, 256, L"Index: %u", pCurrAddresses->IfIndex);
fwprintf(fLog, netAddressLog);
pCurrAddresses = pCurrAddresses->Next;
}
} else {
fwprintf(fLog, L"GetAdaptersAddresses() error");
}
if (pAddresses) {
FREE(pAddresses);
}
}
int main(int argc, char **argv) {
errno_t error = _wfopen_s(&fLog, L"log.txt", L"a+");
netinfo();
fclose(fLog);
}
So, when trying to access pCurrAddresses->IfIndex it's where the program fails, after the first loop (in which it logs some weird large number for index). I am trying to compare mi slightly modified code to the one from MSDN but I can't figure it out.
I know my code needs better organization but for now this is a blocker
There is some problem in the while loop block:
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
/* a } is missing here*/
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));
The good corrected code could be:
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
}
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));

Allegro 5 game: game loop that runs at constant speed?

What is the best way to code a game loop in Allegro 5 that always runs at the same speed, and that properly separates drawing logic from update logic? Should I use threads or not? Should I make use of the new Allegro event system?
Taken from the allegro wiki:
al_install_timer(1.0 / FPS);
...
while (1) {
al_wait_for_event(queue, &event);
/* handle input events */
if (event.type == ALLEGRO_EVENT_TIMER) {
handle_game_tick();
need_redraw = true;
}
if (need_redraw && al_event_queue_is_empty(queue)) {
render_last_frame();
need_redraw = false;
}
}
If you want frame skipping, skip the render_last_frame() command whenever you detect that you are lagging behind in frames (e.g. by using the al_current_time() function).
Here is a more complete version of Allefant's answer (follow the link for detailed line-by-line explanation):
#include <stdio.h>
#include <allegro5/allegro.h>
const float FPS = 60;
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
bool redraw = true;
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
timer = al_create_timer(1.0 / FPS);
if(!timer) {
fprintf(stderr, "failed to create timer!\n");
return -1;
}
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
al_destroy_timer(timer);
return -1;
}
event_queue = al_create_event_queue();
if(!event_queue) {
fprintf(stderr, "failed to create event_queue!\n");
al_destroy_display(display);
al_destroy_timer(timer);
return -1;
}
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_start_timer(timer);
while(1)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_TIMER) {
redraw = true;
}
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
break;
}
if(redraw && al_event_queue_is_empty(event_queue)) {
redraw = false;
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
}
}
al_destroy_timer(timer);
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}

Resources