Find Argv[i] in /bin and /sbin


 
Thread Tools Search this Thread
Top Forums Programming Find Argv[i] in /bin and /sbin
# 1  
Old 07-04-2019
Find Argv[i] in /bin and /sbin

Hello all, I am currently working on a package manager in C and am at the point where I am trying to check to see if the package is already installed. To do this I am taking the package name(s) as an argument using argv. The working code for doing this as follows:

Code:
#include <stdio.h>
#include <sys/stat.h>

#include<dirent.h>

int main(int argc, char *argv[])
{
        short i;
        struct stat program;

        for (i = 1; i < argc; i++) {

                if (stat(argv[i], &program) == 0)
                        return 0;

                else
                        return 1;
        }
}

This works, I have tested it with prints and everything. The issue with this is that it does not check /bin and /sbin, but rather checks the directory it is being run from. So I did some research and wrote a separate .c file to list /bin which is as follows:


Code:
#include <stdio.h>
#include <dirent.h>

short open(char *directory)
{
        struct dirent *de;
        DIR *dr = opendir(directory); /* directory to open */

        if (dr == NULL) {
                printf("directory could not be opened");
                return 0;
        }

        while ((de = readdir(dr)) != NULL) /* print entries in dr */
                printf("%s\n", de->d_name);

        closedir(dr);
        return 0;
}

int main()
{
        open("/bin");
}

this also works. The issue I am having is I can't figure out how to



A) List both /bin and /sbin


B) Check for the program in those directories (this one is the one I really need help with).


Now for checking both I figure I can say basically


Code:
if argv[i] isn't found in /bin check /sbin (if more than one is given then check for all of them and if any were found say which were)

If I can get B solved than A should be pretty easy. I just can't for the life of me figure it out, I would love some advice. Thank you for reading.


Edit:


Progress! Oh sweet sweet progress on this issue I have been stuck on for weeks, so after thinking with a clear head I realized my first function checks for the file and my second opens the directory. All I needed to do was combine them, so I did so and got this:


Code:
#include <stdio.h>
#include <sys/stat.h>

#include <dirent.h>

int main(int argc, char *argv[])
{
        struct dirent *de;
        DIR *dr = opendir("/bin"); /* directory to open */

        short i;
        struct stat program;

        if (dr == NULL) {
                printf("directory could not be opened");
                return 0;
        }

        while ((de = readdir(dr)) != NULL) {
                for (i = 1; i < argc; i++) {

                        if (stat(argv[i], &program) == 0) {
                                printf("found\n");
                                closedir(dr);
                        }

                        else {
                                printf("not found\n");
                                closedir(dr);
                        }
                }
        }

        return 0;
}

Now this always prints not found, I am still working on this but am having a hard time debugging it.

Last edited by realpath_issue; 07-04-2019 at 08:23 PM.. Reason: added updated code (still a work in progress)
# 2  
Old 07-04-2019
First off /bin and /sbin may be and often are symbolic links to /usr/bin or /usr/sbin. There are links for library directories as well.

So I am not sure where your confusion arises.

One solution is the realpath() function. It resolves the problem of reading and resolving links. You can use lstat to check if /bin or whatever is a symlink, too. lstat only returns information about links, not regular files or directories.

Read man page on realpath and lstat
# 3  
Old 07-04-2019
I was unaware of these functions and will definitely take a look at those manpages, thank you so much


Edit:


Oh, I apologize but there seems to be some confusion. What this does is it checks /bin and /sbin to see if the program(s) given are found. So say I run


Code:
check echo

it will look in /bin and /sbin to see if echo is found. If found it will say "found" otherwise it will say "not found". Now my current code has an issue that I can't find a solution for


Code:
#include <stdio.h>
#include <sys/stat.h>

#include <dirent.h>

int main(int argc, char *argv[])
{
        struct dirent *de;
        DIR *dr = opendir("/bin"); /* directory to open */

        short i;
        struct stat program;

        if (dr == NULL) {
                printf("directory could not be opened");
                return 0;
        }

        while ((de = readdir(dr)) != NULL) {
                for (i = 1; i < argc; i++) {

                        if (stat(argv[i], &program) == 0) {
                                printf("found\n");
                                closedir(dr);
                        }

                        else {
                                printf("not found\n");
                                closedir(dr);
                        }
                }
        }
}

stat is checking the current working directory and not /bin, how do I have it look at /bin?


I am also trying with strcmp() and I can't seem to get that working either:


Code:
#include <stdio.h>
#include <sys/stat.h>

#include <string.h>
#include <dirent.h>

int main(int argc, char *argv[])
{
        struct dirent *de;
        DIR *dr = opendir("/bin"); /* directory to open */

        short i;
        struct stat program;

        if (dr == NULL) {
                printf("directory could not be opened");
                return 0;
        }

        while ((de = readdir(dr)) != NULL) {
                for (i = 1; i < argc; i++) {

                        if (strcmp(de->d_name, argv[i]) == 0) {
                                printf("found\n");
                                closedir(dr);
                        }

                        else {
                                printf("not found\n");
                                closedir(dr);
                        }
                }
        }
}


Last edited by realpath_issue; 07-04-2019 at 09:37 PM.. Reason: added details
# 4  
Old 07-04-2019
What you want is the equivalent of the which command - it uses the PATH variable to decide where to look.

Code:
#!/bin/bash
# usage: ./check executable_name_goes_here
# 
export PATH=/bin:/usr/bin:/usr/sbin

/usr/bin/which  "$1" 

exit

change whatever you need to make this work for you.
You do NOT want to duplicate a correct which command, it is a lot of work. If you want to learn instead: download Linux coreutils - google for your UNIX flavor. Then read the source. PS: realpath() is the heart of the which command.
# 5  
Old 07-05-2019
I can't find any source code for which command anywhere, maybe because it's so late I don't know. I was able to implement realpath the issue is I can't figure out how to do basically



Code:
if realpath == 0 (as in found)


return 0


else (as in not found)


return 1


So I got this


Code:
#include <stdio.h>
#include <stdlib.h>

#include <dirent.h>

int main(int argc, char *argv[])
{
        struct dirent *de = calloc(1, sizeof(struct dirent));
        DIR *dr = opendir("/bin"); /* directory to open */

        short i;
        char *res = realpath(argv[i], NULL);

        if (dr == NULL) {
                printf("directory could not be opened");
                return 0;
        }

        while ((de = readdir(dr)) != NULL) {
                for (i = 1; i < argc; i++) {

                        if (res == NULL) {
                                printf("found\n");
                                closedir(dr);
                        }

                        else {
                                printf("not found\n");
                                closedir(dr);
                        }
                }
        }
}

and based on the man page it should be working. I have tried



Code:
./a.out echo //echo is in /bin


// returns not found and 



./a.out ifjie4hfirhghrighih //not in /bin


// returns not found

I am very confused as to why this doesn't work as it seems it should be.
# 6  
Old 07-05-2019
On my home debian linux system, 'which' is a shell script.
So looking at the source is just using cat against it.

Quite short script as well.

Regards
Peasant.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

/usr/bin/ld: cannot find -lboost_regex-mt

...... (30 Replies)
Discussion started by: larry burns
30 Replies

2. UNIX and Linux Applications

/usr/bin/ld: cannot find -lz error

I am installing lxml module for python on redhat I have installed libxml2 already. When I run for libxslt: ./configure --prefix=libxslt_folder --with-libxml-prefix=libxml2_folder It is ok the I run : make I have error: /usr/bin/ld: cannot find -lz collect2: ld returned 1 exit status I... (4 Replies)
Discussion started by: AIX_30
4 Replies

3. Shell Programming and Scripting

If cmd in in "A/user/bin A/bin A/user/sbin" but not "B/user/bin B/bin B/user/sbin" directory print t

there are two directories A and B if cmd in in "A/user/bin A/bin A/user/sbin" but not "B/user/bin B/bin B/user/sbin" directory print them (1 Reply)
Discussion started by: yanglei_fage
1 Replies

4. UNIX for Advanced & Expert Users

O argv, argv, wherefore art thou argv?

All of my machines (various open source derivatives on x86 and amd64) store argv above the stack (at a higher memory address). I am curious to learn if any systems store argv below the stack (at a lower memory address). I am particularly interested in proprietary Unices, such as Solaris, HP-UX,... (9 Replies)
Discussion started by: alister
9 Replies

5. Programming

/usr/bin/ld: cannot find -lpam

I'm trying to compile sudo on RHEL 4.8 and during the make I get the this error. Does anyone know what package I'm missing? gcc -o sudo sudo_auth.o pam.o mkstemps.o ldap.o exec_pty.o get_pty.o iolog.o audit.o boottime.o check.o env.o exec.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o... (2 Replies)
Discussion started by: woodson2
2 Replies

6. Shell Programming and Scripting

#!/bin/bash cannot find file or directory

Hello, When i run a bash script on ubuntu i get this message.. #!/bin/bash cannot find file or directory... Can anibody help me with this, because the file actually exists.... Is there any extra configuration to be made? (5 Replies)
Discussion started by: oliveiraum
5 Replies

7. Red Hat

/usr/bin/find && -exec /bin/rm never work as expected

hi there, Would you able to advise that why the syntax or statement below couldn't work as expected ? /usr/bin/find /backup -name "*tar*" -mtime +2 -exec /bin/rm -f {} \; 1> /dev/null 2>&1 In fact, I was initially located it as in crontab job, but it doesn't work at all. So, I was... (9 Replies)
Discussion started by: rauphelhunter
9 Replies

8. Solaris

different between /sbin/init and /usr/sbin/init

root@test09 # ls -al /sbin/init -r-xr-xr-x 1 root sys 550000 Jun 29 2002 /sbin/init root@test09 # ls -al /usr/sbin/init -r-xr-xr-x 1 root sys 37100 Jun 29 2002 /usr/sbin/init (2 Replies)
Discussion started by: userking
2 Replies

9. UNIX for Dummies Questions & Answers

Difference between /bin, /usr/bin, /sbin ?

Hi All, Can somebody tell me the difference between /bin, /usr/bin, /sbin ? Thanx in advance, Saneesh Joseph (3 Replies)
Discussion started by: saneeshjose
3 Replies

10. Shell Programming and Scripting

command find returned bash: /usr/bin/find: Argument list too long

Hello, I create a file touch 1201093003 fichcomp and inside a repertory (which hava a lot of files) I want to list all files created before this file : find *.* \! -maxdepth 1 - newer fichcomp but this command returned bash: /usr/bin/find: Argument list too long but i make a filter all... (1 Reply)
Discussion started by: yacsil
1 Replies
Login or Register to Ask a Question