how to use long options in c? - c

how to use long options via getopt_long:
for example like this:
--wide-option
I have --wide and -w.
And on --wide-option it gives the following error:
"unrecognized option"
int main(int argc, char **argv)
{
    struct option opts[] =
    {
        {"wide", 1, 0, 'w'},
        {
            0, 0, 0, 0
        }
    };
    int option_val = 0;
    int counter = 10;
    int opindex = 0;
    while ((option_val = getopt_long(argc, argv, "w:", opts, &opindex)) != -1)
    {
        switch (option_val)
        {
        case 'w':
            if (optarg != NULL)
                counter = atoi(optarg);
            for (int i = 0; i < counter; i++)
                printf("Hello world\n");
            break;
        default:
            return 0;
        }
    }
    return 0;
}

If you look at the cat source code (here), you can see that --number and --number-nonblank are two different options (-b and -n). (near line 555).
If you want to do the same, you can that way:
#include <getopt.h>
#include <stdio.h>
int main(int argc, char **argv)
{
struct option opts[] =
{
{"wide", 1, 0, 'w'},
{"wide-option", 0, 0, 'o'}, /* declare long opt here */
{
0, 0, 0, 0
}
};
int option_val = 0;
int counter = 10;
int opindex = 0;
while ((option_val = getopt_long(argc, argv, "w:o", opts, &opindex)) != -1) /* the case here (I arbitrary choose 'o') */
{
switch (option_val)
{
case 'w':
if (optarg != NULL)
counter = atoi(optarg);
printf("option --wide %d found!\n", counter);
for (int i = 0; i < counter; i++)
printf("Hello world\n");
break;
case 'o': /* and take the case into account */
printf("option --wide-option found!\n");
break;
default:
return 0;
}
}
return 0;
}

Related

User defined functions in c are not switching

problem
I was making a c program in which users details are accepted checked and added to a file
but while compile the functions are not changing i meant it only asks the name and the program end
can someone please help me out!
#include <string.h>
void main()
void regis_name();
void regis_dob();
void regis_pin();
void check();
//checks code is not added here
{
     int a, i, j, n, b, f = 1, d[1], m[1], y[1], f1 = 1;
    int *a1, *d1[1], *m1[1], *y1[1];
    a1 = a;
    d1[1] = &d[1];
    m1[1] = &m[1];
    y1[1] = &y[1];
    regis_pin();
void regis_name()
{
    char name[3];
    printf("ADD YOUR NAME: \n ");
    scanf("%s", name[3]);
   regis_dob(); // to dob
}
bd
void regis_dob()
{
    int a, i, j, n, b, f = 1, d[1], m[1], y[1], f1 = 1;
    printf("enter date in 'dd' month in 'mm' year in 'yyyy' \n \n");
    printf("enter dd:   \n");
    scanf("%d", &d[1]);
    printf("enter mm:   \n");
    scanf("%d", &m[1]);
    printf("enter yyyy:  \n");
    scanf("%d", &y[1]);
   regis_pin; // to pin
}
void regis_pin()
{
    int a;
    printf("ADD A PASS CODE OF 4 DIGIT:  \n");
    scanf("%d", &a);
    printf("\n");
    check(); // to pin check
}```

Why copying data into buffer using memcpy cause buffer to overflow?

I have this function and once in a while it causes a buffer overflow error at the line in bold which is memcpy(&(sin6->sin6_addr), &(inet->address[0]), 16);
Tried executing this function outside of the application, it never caused an issue. What do you all think why would an app crash at this call?
struct mariyo_inet {
uint8_t length; /* Generally 4 or 16- the length of the address, in bytes. */
uint8_t netmask; /* The number of significant bits in the address. */
uint8_t address[16]; /* The address itself. */
} __attribute__((packed));
void mariyo_inet_to_sockaddr(struct mariyo_inet *inet, struct sockaddr *sock, socklen_t *len, uint16_t port_ne)
{
if (inet->length == 16) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sock;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = port_ne;
#ifndef __linux__
sin6->sin6_len = sizeof(*sin6);
#endif
if (len) *len = sizeof(*sin6);
**memcpy(&(sin6->sin6_addr), &(inet->address[0]), 16);**
} else if (inet->length == 4) {
struct sockaddr_in *sin = (struct sockaddr_in *) sock;
sin->sin_family = AF_INET;
sin->sin_port = port_ne;
#ifndef __linux__
sin->sin_len = sizeof (*sin);
#endif
if (len) *len = sizeof(*sin);
memcpy(&(sin->sin_addr),
&(inet->address[0]),
4);
}
}
Here is the application stacktrace,
#7  0x00000000007c94b9 in mariyo_inet_to_sockaddr (inet=inet#entry=0x7ff31a7da940, sock=sock#entry=0x7ff31a7da900, len=len#entry=0x7ff31a7da8f0, port_ne=port_ne#entry=0) at mariyo.c:4959
        sin6 = 0x7ff31a7da900
#8  0x000000000062847a in enzyme_mconn_icmp_transmit_cb () at enzyme_mconn_icmp.c:522
        ret = <optimized out>
        mconn_icmp = <optimized out>
        icmp_buf_len = <optimized out>
        icmp_linear_buf = 0x61d000d6cec8 "E"
        iph = 0x61d000d6cec8
        iph_len = <optimized out>
        icmp_hdr = <optimized out>
        icmpreq_cookie = 0x604000845f68
        icmpinfo = 0x619000355298
        icmpfail_cookie = <optimized out>
        ip_tlen = 1228
#9  0x0000000000603595 in enzyme_mconn_dequeue_data (mconn=mconn#entry=0x624010002b90, need_to_lock=0) at enzyme_mconn.c:547
        ret = 0
        tx_len = 1228
        __FUNCTION__ = "enzyme_mconn_dequeue_data"
#10 0x0000000000608ee5 in enzyme_mconn_send_data_to_client (mconn=mconn#entry=0x624010002b90, buf=buf#entry=0x60e000188218, buf_len=buf_len#entry=1228, need_to_lock=need_to_lock#entry=1) at enzyme_mconn.c:668
        res = 0
        enq_len = <optimized out>
        drop_len = <optimized out>
        __FUNCTION__ = "enzyme_mconn_send_data_to_client"
#11 0x0000000000609b42 in enzyme_client_process_rx_data (mconn=mconn#entry=0x624010003148, buf=buf#entry=0x60e000188218, buf_len=buf_len#entry=1228) at enzyme_mconn.c:952
        peer = 0x624010002b90
        res = <optimized out>
        __FUNCTION__ = "enzyme_client_process_rx_data"
        ip_proto = <optimized out>
This is how it looks at the caller,
int mariyo_string_to_inet(const char *in_str, struct mariyo_inet *inet)
{
char tmp[51];
//
// filling tmp here from in_str
//
/* IPv4 + IPv6 in same address == bad */
if (saw_dot || saw_colon) {
if (saw_colon) {
/* IPv6 (Note: Supports IPv4 in IPv6) */
if (!inet_pton(AF_INET6, tmp, &(inet->address[0]))) {
//fprintf(stderr, "%s:%d: Could not parse IP address <%s>\n", __FILE__, __LINE__, tmp);
return 1;
}
if (!slash) netmask = 128;
if (netmask > 128) {
//fprintf(stderr, "%s:%d: Bad netmask > 128 on IP address <%s>\n", __FILE__, __LINE__, in_str);
return 1;
}
inet->length = 16;
}
return 0;
}
{
.....
socklen_t sock_len;
struct mariyo_inet inet_ip;
struct sockaddr sock_addr;
memset(&inet_ip, 0, sizeof(struct mariyo_inet));
mariyo_string_to_inet(icmpinfo->probe_info.dest_ip, &inet_ip);
memset(&sock_addr, 0, sizeof(struct sockaddr));
mariyo_inet_to_sockaddr(&inet_ip, &(sock_addr), &sock_len, 0);
....
}
struct sockaddr is not guaranteed to be large enough (and usually isn't) to hold an IPv6 address.
Use struct sockaddr_storage instead.

when clang compiling to target wasm, it return error for function declaration

I have tried to generate wasm file from the c program.
clang test.c  --target=wasm32-unknown-unknown-wasm -nostartfiles -nostdlib -Wl,--no-entry -Wl,--export-all -o test.wasm
The content of test.c the file is as follows
extern void __VERIFIER_error(void);
extern void __VERIFIER_assume(int);
void __VERIFIER_assert(int cond) {
  if (!(cond)) {
      ERROR: __VERIFIER_error();
  }
  return;
}
int __VERIFIER_nondet_int();
int test() {
    int x = 1;
    int y = 0;
    while (y < 1000 && __VERIFIER_nondet_int()) {
        x = x + y;
        y = y + 1;
    }
    __VERIFIER_assert(x >= y);
    return 0;
}
Encounter the following error message:
clang test.c  --target=wasm32-unknown-unknown-wasm -nostartfiles -nostdlib -Wl,--no-entry -Wl,--export-all -o test.wasm
wasm-ld: error: /tmp/test-e520f3.o: undefined symbol: __VERIFIER_error
wasm-ld: error: /tmp/test-e520f3.o: undefined symbol: __VERIFIER_nondet_int
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
I have updated content of the file as follows:
extern "C" void __VERIFIER_error(void);
extern "C" void __VERIFIER_assume(int);
extern "C" void __VERIFIER_assert(int cond) {
  if (!(cond)) {
      ERROR: __VERIFIER_error();
  }
  return;
}
extern "C" int __VERIFIER_nondet_int();
int test() {
    int x = 1;
    int y = 0;
    while (y < 1000 && __VERIFIER_nondet_int()) {
        x = x + y;
        y = y + 1;
    }
    __VERIFIER_assert(x >= y);
    return 0;
}
Encounter the following error message, how to get rid of such errors. Can anyone please guide in this regard.
test/test.c:1:8: error: expected identifier or '('
extern "C" void __VERIFIER_error(void);
       ^
test/test.c:2:8: error: expected identifier or '('
extern "C" void __VERIFIER_assume(int);
       ^
test/test.c:3:8: error: expected identifier or '('
extern "C" void __VERIFIER_assert(int cond) {
       ^
test/test.c:9:8: error: expected identifier or '('
extern "C" int __VERIFIER_nondet_int();
       ^
test/test.c:13:24: warning: implicit declaration of function '__VERIFIER_nondet_int' is invalid in C99 [-Wimplicit-function-declaration]
    while (y < 1000 && __VERIFIER_nondet_int()) {
                       ^
test/test.c:17:5: warning: implicit declaration of function '__VERIFIER_assert' is invalid in C99 [-Wimplicit-function-declaration]
    __VERIFIER_assert(x >= y);
    ^
2 warnings and 4 errors generated.
You have two functions without definitions. You do not link any libraries or other object files. So linker is not finding them and issues the error message.

Strtok:I dont know why this program keeps failing

In this program the char *token is initialized with a weird garbage value.I am unable to sort it out. Here's the source code:
#include<iostream>
#include<string.h>
#include<stdlib.h>
void fetch_value(char *string,int pos,char *dest)
{
    char *token;
    int i=0;
    token=strtok(string,",");
    if(pos>1)
    {
        token=strtok(NULL,",");
        while(i<pos-1){
            token=strtok(NULL,",");
            printf("token =%s\n",token);
            i++;
        }
        strcpy(dest,token);
    }
    else
    {
        strcpy(dest,token);
    }
}
int main(void)
{
    char checking[100];
    memset(checking,0x00,sizeof(checking));
    fetch_value("14174000100,35679700322,35679700322,35679700322,
            35679700322,14174000999,919440710210000,1",0,checking);
    printf("checking=%s\n",checking);
    return 0;
}
Your help, feedback or suggestions is greatly appreciated.
The first argument of strtok must be modifiable. Your code passes a string literal, which is not modifiable. This leads to undefined behavior.
The simplest modification that will fix the problem is as follows:
char numList[] = "14174000100,35679700322,35679700322,35679700322,35679700322,14174000999,919440710210000,1";
fetch_value(numList, 0, checking);
You should also note that strtok is an older function which is not reentrant, because it uses static variables to save its state. In the new code you should use the reentrant version of the function - strtok_r, which requires you to pass memory for saving the state.
Do this instead:
int main(void)
{
char checking[100];
memset(checking,0x00,sizeof(checking));
char string[] = "14174000100,35679700322,35679700322,35679700322,
35679700322,14174000999,919440710210000,1";
//now string can be modified.
fetch_value(&string[0],0,checking);
printf("checking=%s\n",checking);
return 0;
}

rearranging an array of data without using temporary array

How can I rearrange an array if I know where to put each element in array without using temporary array?
I guess, This has something to do with cyclic permutation but I cannot figure out how they can be linked each other. Wiki page seems irrelevant to me(http://en.wikipedia.org/wiki/Cyclic_permutation)
If you know both where to put each element in the array, and also which element of the array belongs at a specific index, then you can use that information to optimise your rearrangement. Otherwise you can iterate over all the array elements exchanging them into the correct location until they are all correctly placed.
void permuteObjects(Object[] elements, int[] positions)
{
for (int i = 0; i < elements.length; ++i) {
while (positions[i] != i) {
swapObjects(elements, i, positions[i]);
swapIntegers(positions, i, positions[i]);
}
}
}
If you can boil down the "re-arrangement" of your array to single permutations, i.e. to swapping the values of two elements then you can use the XOR to perform the swap without additional variable.
Here a sample code from the linked Wikipedia article:
void xorSwap (int *x, int *y) {
if (x != y) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
Why not just use a temporary array and terminate it by setting it to null?
Maybe take a look at http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
HashMaps dynamicly increase when adding new items.
Use like this:
HashMap<Integer, WhatEverYouWantToStore> = new HashMap<Integer, WhatEverYouWantToStore>();
Maybe try this:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class sort {
        public static void main(String[] args) {
                List list = new ArrayList();
                String country[] = { "India", "Japan", "USA", "UK", "Nepal" };
                for (int i = 0; i < 5; i++) {
                        list.add(country[i]);
                }
                Collections.sort(list);
                Iterator i = list.iterator();
                while (i.hasNext()) {
                        System.out.print(i.next() + "\t");
                }
        }
}

Resources