Find Argv[i] in /bin and /sbin


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
# 1  
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 FOSSilized; 07-04-2019 at 09:23 PM.. Reason: added updated code (still a work in progress)
# 2  
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  
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 FOSSilized; 07-04-2019 at 10:37 PM.. Reason: added details
# 4  
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  
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  
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 for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #921
Difficulty: Medium
Unix Epoch Time cannot be extended backwards from the epoch date.
True or False?

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

Featured Tech Videos