"Unknown Command" error when passing "uname" to execv() - c

So I have to build a program in C that practically takes a command from keyboard , split it into tokens that are stored in an array and use those tokens as input to "execv" (a command in ubuntu) , I chose the command "uname" with the parameter "-a", but for some reason it keeps saying "Comanda necunoscuta!" (Unknown Command!) Heres my code:
#include <stdio.h>
#include<stdlib.h>
#include <string.h> /*strtok strcpy*/
#include<malloc.h> /*malloc*/
#include <sys/types.h> /* pid_t */
#include <sys/wait.h> /* waitpid */
#include <unistd.h> /* _exit, fork */
int main()
{
int i=0;
char *cuvinte[256]; //words
char comanda[256]; //command
printf("Introduceti comanda: "); // command input
fgets(comanda,sizeof(comanda),stdin); // read command
char *c = strtok(comanda," "); // break command into tokens
while(c!=0)
{
cuvinte[i] = malloc( strlen( c ) + 1 ); //alocate memory
strcpy(cuvinte[i++],c); // copy them
printf("%s\n",c); // print them
c=strtok(NULL, " ,.!?");
}
printf("Sunt %d elemente stocate in array! \n\n",i); // no of elements stored
printf("Primul cuvant este: %s \n\n",cuvinte[0]); // shows the first token
if((cuvinte[0]=='uname')&&(cuvinte[1]=='-a')){ // here lays the problem i guess
/*face un proces copil*/
pid_t pid=fork();
if (pid==0) { /* procesul copil*/
static char *argv[]={"/bin/uname","-a",NULL};
execv(argv[0],argv);
exit(127); /*in caz ca execv da fail*/
}
else { /* pid!=0; proces parinte */
waitpid(pid,0,0); /* asteapta dupa copil */
}
}
else printf("Comanda necunoscuta !\n"); // problem
//getch();
return 0;
}

Firstly add
cuvinte[1][strlen(cuvinte[1])-1]='\0';
after the while loop and just before "printf("Sunt %d elemente stocate in array! \n\n",i);"
second thing
use
if((strcmp(cuvinte[0],"uname")==0) && (strcmp(cuvinte[1],"-a")==0))
instead of "=="
program will work !!

First of all, I don't have enough reputation to post a comment sorry for that.
I'm not sure you can compare two strings with the '==' operator in C. Try using the strcmp function.

Related

C: variables retain the value from previous operation instead of resetting

I am fairly new to C and have been trying my hand with some arduino projects on Proteus. I recently tried implementing a keypad and LCD interface with Peter Fleury's libraries, so far the characters I input are displayed fine, but I run into a problem when trying to print to the serial port. It's like the value of the keys keeps on being concatenated with every iteration so the ouput has extra characters like this:
The value before the comma is from the 'key' variable, the value after it the 'buf' variable:
151
(The 5 I input in the second iteration was added to the 1 from the first iteration and then put into the variable I print)
I figure it may be due to my lack/incorrect use of pointers, heres is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include "lcd.h"
#include "mat_kbrd.h"
#include "funciones.h"
#include "menu.h"
char buf[256];
char* coma = ",";
int main(void)
{
pin_init();
serial_begin();
lcd_init(LCD_DISP_ON);
kbrd_init();
bienvenida();
while (1) {
int i = 0;
char key = 0;
//char *peso;
//int pesoSize = 1;
char peso[100];
//peso = calloc(pesoSize,sizeof(char));
int salida = 0;
lcd_clrscr();
desechos();
key = kbrd_read();
if (key != 0) {
lcd_gotoxy(0,3);
lcd_putc(key);
_delay_ms(2000);
lcd_clrscr();
cantidad();
while (salida != 1) {
char keypeso = 0;
keypeso = kbrd_read();
//pesoSize = i;
//peso = realloc(peso,pesoSize*sizeof(char));
if (keypeso != 0) {
if (keypeso == '+') {
salida = 1;
keypeso = *("");
lcd_clrscr();
calcularTotal(key,peso);
_delay_ms(2000);
} else {
lcd_gotoxy(i,1);
lcd_putc(keypeso);
snprintf(peso, sizeof peso, "%s%s",peso, &keypeso);
//strcat(peso,&keypeso);
i++;
_delay_ms(2000);
}
}
}
snprintf(buf, sizeof buf, "%s%s%s", &key,coma,peso);
serial_println_str(buf);
}
}
}
&key and &keypeso point to a single char, but you are using the %s format specifier, so trying to read a string into a single char. Use %c rather then %s for single characters, and pass the char not the address-of-char..

My C code aint stop and i can't end the loop

What am I doing wrong? My code keeps in loop and n goes minus. It was supposed to return 0; at 0.Also whatever I do it starts with 3-2-1-0 even I type "2" it still keeps doing it 3-2-1-0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
static const char PSWRD[]="1234";
char p[6];
int n=3, y;
printf("Hos geldiniz");
do{
printf("\n\nOgrenci_ID:Elif");
fflush(stdout);
printf("\nSifre:");
scanf("%s", &p);
fflush(stdout);
y=strcmp(p, PSWRD);
if(y==0){
printf("\nGiris Basarili"); `//succesfull login`
return 0;
}else {
printf("Yanlis Sifre, tekrar deneyiniz", 3-n); //wrong password try again
printf("\nKalan hakkiniz ");
printf("%d\n", n);
getchar();
n--;}
if(n<1){
printf("\nHesabiniz bloke oldu");
return 0;
// that means you use all your chance and now you're blocked but my code aint stop here and n goes minus
}
// I am not exactly sure about "3"
//Also what ever i do it starts with 3-2-1-0 even i type "2" it's still keep doing it 3-2-1-0
}while (n<=3);
return 0;
}
while (n<=3);
doesn't agree with
n--;
You seem to want
while (n>0);
Its working for me!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
static const char PSWRD[]="1234";
char p[6];
int n=3, y;
printf("Welcome");
do{
printf("\n\nStudent_ID:Elif");
fflush(stdout);
printf("\nPassword:");
scanf("%s", p);
fflush(stdout);
y=strcmp(p, PSWRD);
if(y==0){
printf("\nSucessfull Login\n"); //succesfull login
return 0;
}else{
n--;
printf("\nWrong password, try again: "); //wrong password try again
printf("\nRemaining attempts ");
printf("%d\n", n);
getchar();
}
if(n<1){
printf("\nYour account has been blocked\n");
return 0;
}
}while (n>0);
}
When user introduces wrong password, you have more 2 tries and if you enter the password wrong on thats 2 tries program ends! But if you insert it right program makes login, so works fine
In your code, there is no increment of 'n', so the loop keeps going (because n is always smaller than 3). I'm not too sure of what you're trying to do, but you need to change your 'while' condition or statements of 'n' inside the loop.
Currently the loop keeps running forever:
When n=3 - > 3<=3 is true.
When n=2 - > 2<=3 is true.
Etc.
The only way it's going to end is when n decrements until it is equal to the absolute minimum value of an integer which is -2,147,483,648, then it will decrement one more time and change to 2,147,483,647 and the loop will end.
Use printf to watch the value of n, and you will quickly observe that your condition for the do...while loop is incorrect.
However, note the conditional, if(n<=0) with return.
Provide a minimal reproducible example, such as below...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int login(char* PSWRD)
{
int n=3, y;
char p[100+20];
printf("Hos geldiniz");
do{
printf("\nSifre:");
scanf("%100s", p); // limit input size, use p, not &p
if( 0 == strcmp(p, PSWRD) ) {
printf("\nsuccess!");
return 0;
}
printf("Yanlis Sifre, tekrar deneyiniz"); //wrong password try again
n--;
if(n<=0)
{
printf("\nHesabiniz bloke oldu");
return -1;
}
printf("n=%d\n",n); // print current n
} while (n<=3); // this should be (n>0)
return -1;
}
int main()
{
char* PASSWD = "password";
int result;
if( 0 > login(PASSWD) ) {
printf("\nfailed!\n");
exit(1);
}
printf("\nsuccess!\n");
// continue processing here
}
Caveat: Make sure you limit input size to avoid buffer overflow
Read no more than size of string with scanf()

Unix - Writing a line from a file to a char* var, then saving it in integers

Question: I have a file, called ATM1, and it is filled with strings, for example(this is the format for everyline): O ilan 123 456 Which means - O stands for open account, ilan is username, 123 is password, and 456 is initial amount in my bank account.
After opening the file, iterating with a while loop while(((ret_in = read (in1, &buffer1, BUF_SIZE)) > 0)), I want to get the line's details and store them in the appropriate variables. for example the first char will be stored in a variable called letter or msg[0] whatever is more convenient for you, then there is a space and then username, then password, and optional stuff like balance, or maybe another account id (for transfer money purposes).
Every ATM machine should be a thread, it has its own file, for now it is just one file "ATM1" because I want it to work in the beginning for at least one file.
Current Problem:
Segmentation fault in the OpenFile function. I'm still not able to store the line's values in the appropriate variables and called the switch statement for opening account, etc.
Here is the current code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>
#define BUF_SIZE 8192
sem_t log;
void OpenNewAccount(int acc,int pw,int amount){
}
struct Account{
int number;
int password;
int balance;
};
//*Opens file for every ATM
void* openFile(void* args){
//To add later: while(true) { sleep(100); do next file's line }
//Open file
int* aargs = args;
int acc;
int pw;
int amount;
int target_acc;
int ret_in, in1,file;
char buffer1[BUF_SIZE];
int count = 0;
int i = 0;
char fn[5] = "ATM1";
char* msg;
file = open(fn,O_RDONLY|O_CREAT,0644);
while(((ret_in = read (file, &buffer1, BUF_SIZE)) > 0))
{
for(i; i<ret_in; i++)
{
if(buffer1[i]!='\n')
msg[i] = buffer1[i];
/* else{
if(count == 0){
count++;
break;
}
else
{
count = i + 1;
break;
}
}
*/
}
}
printf("%s", msg); //TEST: check msg
//Here we translate the message
/*
//Here we call the relevant function of the msg
switch (msg[count - 1]){
case 'O': OpenNewAccount(acc,pw,amount);
case 'D': Deposit(acc,pw,amount);
case 'W': Withdrawl(acc,pw,amount);
case 'B': Balance(acc,pw);
case 'Q': CloseAccount(acc,pw);
case 'T': Transfer(acc,pw,target_acc,amount);
}
*/
}
//*finish: Update log.txt and lock it
void WriteLog(char* msg){
int file;
char logName[8] = "log.txt";
sem_wait(&log);
file = open(logName,O_WRONLY|O_CREAT,0644);
strcat(msg,"\n");
write(file,&msg,strlen(msg));
close(file);
sem_post(&log);
}
int main(void)
{
int i,n,a;
sem_init(&log, 0, 1);
printf("Please enter the number of ATMs you want: \n");
scanf("%d", &n);
int bank; //bank with n ATMs
pthread_t thread[3];
printf("test\n"); //TEST: check msg
for(i = 0; i < 3; i++)
pthread_create ( &thread[i] , NULL , openFile , &i);
scanf("%d",&a);
}
Well, for one, you use i as an array index without ever initializing it. That could easily cause a SEGFAULT.
But honestly this whole thing is a mess. Your function names don't do what they say they do. You appear to be thrashing around almost randomly. I suggest you rethink your design from the beginning. Go through the "top down" design process you should have learned and figure out how to factor your code. Only then should you proceed.

Auto-completion visual not good (readline.h)

I would like to add the auto completion on the shell I created. I could not put the entire code but I can tell you my shell is working!
So I tried to implement auto-completion by using the readline function but the result is not that great (see the code in commentary I tried): the auto-completion works but the problems are:
1. I need to press twice enter to get the command executed now. 2. I need to type twice the command (like "ls") to get it executed! Can you help me to fix this? thank you :)
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <stdio.h>
#include "includes/ft_sh1.h"
int main(int ac, char **av, char **envp)
{
char *line;
t_env *e = NULL;
char *add;
if (!(e = (t_env *)malloc(sizeof(t_env))))
return (0);
e->envp = env_cpy(envp, 0, 0);
init_env(e);
while (1)
{
--> My question is only about this part below <--
ft_printf("shell$> ");
// add = readline( "shell ");
// add_history(add);
// printf("%s", add);
--> My question is only about this part above <--
get_next_line(0, &line);
get_pwd_env(e);
e->cmd = get_cmd(e, line);
if (ft_strcmp(line, "exit") == 0)
exit(0);
else if (ft_strncmp(e->cmd[0], "cd", 2) == 0)
cd_cmd(e);
else
ft_execute(av, line, e);
}
}
When you just uncomment the part of code in question, you still have the call
get_next_line(0, &line);
in your program, so no wonder that you need to type two command lines.

Getting the error "undefined reference to". Can you explain what it means and where I have made the mistake?

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <sys/types.h>
#include <crypt.h>
#include "pwent.h"
#define TRUE 1
#define FALSE 0
#define LENGTH 16
void sighandler() {
signal(SIGINT,SIG_IGN);
}
int main(int argc, char *argv[]) {
mypwent *passwddata;
/* see pwent.h */
char important[LENGTH] = "***IMPORTANT***";
char user[LENGTH];
char prompt[] = "password: ";
char swap_prompt[]="New password: ";
char again_prompt[]="Again: ";
char *user_pass;
char *new_pass;
char *again_pass;
int f_login;
char *en_pass;
char *envp[] = { NULL };
char *argvv[] = { "/bin/sh",NULL};
sighandler();
while (TRUE) {
/* check what important variable contains - do not remove, part of buffer overflow test */
printf("Value of variable 'important' before input of login name: %s\n",
important);
printf("login: ");
fflush(NULL); /* Flush all output buffers */
__fpurge(stdin); /* Purge any data in stdin buffer */
if (fgets(user,16,stdin) == NULL) /* gets() is vulnerable to buffer */
{
exit(0); /* overflow attacks. */
}
*/* check to see if important variable is intact after input of login name - do not remove */*
printf("Value of variable 'important' after input of login name: %*.*s\n",
LENGTH - 1, LENGTH - 1, important);
user_pass = getpass(prompt);
passwddata = mygetpwnam(user);
if (passwddata != NULL) {
en_pass=crypt(user_pass,passwddata->passwd_salt);
if (!strcmp(en_pass, passwddata->passwd)) {
if(passwddata->pwage==10){
printf("You need to swap your password!!! \n");
do{
new_pass=getpass(swap_prompt);
again_pass=getpass(again_prompt);
}while(strcmp(new_pass,again_pass));
printf("Password changed!!! \n");
passwddata->passwd=new_pass;
passwddata->pwage=0;
}else{
printf(" You're in !\n");
printf("Number of failed login is %d\n", passwddata->pwfailed);
passwddata->pwfailed=0;
passwddata->pwage++;
}
mysetpwent(user,passwddata);
setuid(passwddata->uid);
execve("/bin/sh",argvv,envp);
}else{
if(passwddata->pwfailed==3){
printf("You attempted too many times \n");
passwddata->pwfailed=0;
mysetpwent(user,passwddata);
return 0;
}
printf("Wrong password, please try again!!! \n");
f_login++;
passwddata->pwfailed=f_login;
mysetpwent(user,passwddata);
}
}else{
printf("Login Incorrect \n");
}
}
return 0;
}
So I get the error "undefined reference to mygetpwnam" and "undefined reference to mysetpwent". I am not sure what this exactly means and how to go about correcting it. This is a part of an assignment I am working on with regards to unix and their password systems.
You attempt to call the function mygetpwnam once in your code, and mysetpwent three times, yet those functions are not defined anywhere. Hence, you reference something undefined, an error.
"mygetpwnam" and "mysetpwent" are defined in pwd.h. Open and check if pwd.h has definition for "mygetpwnam" and "mysetpwent".
Check pwent.h to see if your functions are declared there (definition should be in pwent.c). Also make sure you haven't misspelled the function names. You should show us how you compile the program.

Resources