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)
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.
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
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.
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.
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)
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)
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)
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)
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)
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)