My cd function does not go to the home directory - c

I am building a custom shell in c, and one of the requirements is that the folder from while you run the program must be the "home" folder.
That is, if you type in just cd or cd ~ you should get to that directory. I have implemented it, but it is not working.
char *basedir;
void init_prompt()
{
getcwd(cwd,100);
basedir = cwd;
}
void cd_me(char **argv)
{
chdir(argv[1]);
if(getcwd(cwd,100)!=0)
{
;
}
if(strcmp("~\0",argv[1])==0||strcmp("\0",argv[1])==0)
chdir(basedir);
}
Any suggestions on how to fix this?
Also when I print basedir I am getting the correct output.

char *basedir;
basedir = cwd;
You make basedir a synonym to cwd. Whenever cwd changes, basedir follows. It's a pointer, it cannot remember its own string, it can only point to someone else's string.
You must make a copy instead.
char basedir[100];
strcpy(basedir,cwd);
Add bounds checks and error handling as needed.

Related

chdir(getenv("HOME") returns Bad address

char *home = getenv("HOME");
if (!strcmp(t->argv[0], "cd")) {
if (!t->argv[1]) {
chdir(home);
}
if (chdir(t->argv[1])) {
perror(t->argv[1]);
}
}
what this is supposed to do is run the cd command with the provided argument, and if there is no argument provided then return to the home directory. if i call cd without an argument, chdir prints "Bad address". i dont know why, considering i printed the value that getenv("HOME") returns and entered that path manually in my shell and it worked fine. why does it work when i provide the value but not when getenv provides it?
I also cant manually code a path for home either because it has to run on other machines. i need it to work with getenv("HOME").
i was being an idiot, as #dimich pointed out. the first chdir worked fine, but the second if statement should be an else if.
new code:
char *home = getenv("HOME");
if (!strcmp(t->argv[0], "cd")) {
if (!t->argv[1]) {
chdir(home);
} else if (chdir(t->argv[1])) {
perror(t->argv[1]);
}
}

How to check if path is a subdirectory of another

How I can check if path is a sub-directory of another ?
I want to check this because I don't want to allow the user to go forward of the path given as argv of my program.
I did that :
bool can_move(char *base, char *new)
{
return (strncmp(base, new, strlen(base)) == 0
&& (access(new, F_OK) == 0));
}
But the problem is how can I mange the './' and the '../' ?
Thanks !
Get the realpath() for argument and path where the user want to go .
Be sure that user realpath() is argument realpath() or start with argument realpath()/

How to get /etc/ directory

I have function:
gint isfileexists(gchar *filename)
{
struct stat buffer;
gint i = stat(filename, &buffer);
if (i == 0) {
return 1;
}
return 0;
}
and if I call them:
isfileexists("/etc/myfile")
it search "myfile" in "/home/user/etc/myfile". How to do this well?
It should only look for /home/USER/etc/myfile if:
you leave off the leading / when calling isfileexists; and
that directory /home/USER is your current working directory.
In other words, if the argument is a relative path name.
Since you have the leading /, it will be an absolute path name and should access /etc/myfile.
If I've misunderstood and you actually want the one in your home directory, you can use getenv("HOME") to get your home directory and then append /etc/myfile with strcat. That will also work regardless of your current working directory.

problems with searching in files and directories .. windows programming

I'm studying this book (Addison Wesley Windows System Programming 4th Edition) and I think its useless Im working on a searching code that support the recursive so it can go in deepth in files and directories the code is working ( I guess ) no syntax error but the output is not what I want the out put of the search is like:
not found
Now, here are the folders:
not found
Searching in d:\iust\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\..\e-books\.\.\.\.\E-BOOKS
The file name is: d:\iust\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\..\e-books\.\.\.\.\E-BOOKS\*Test*
not found
Now, here are the folders:
not found
Searching in d:\iust\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.
\.\.\.\.\.\..\e-books\.\.\.\..
The file name is: d:\iust\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\
.\.\.\.\.\.\.\.\..\e-books\.\.\.\..\*Test*
not found
Now, here are the folders:
First I notiiced that what ever I do it will not search just inside the folder i specified but in all whole drive and the second annoying probem is the DOTS the . and .. those appear in each folder how can I avoid this problem. now as i said before Im using the book I mentioned before but I dont know I just dont like what i did is there a better way to form my code .
the code :
#include "stdafx.h"
#include <windows.h>
void SearchForFile(TCHAR *folder, TCHAR *file){
_tprintf(L"Searching in %s\n",folder); //just to show the state
TCHAR temp[1000];
_stprintf(temp,L"%s\\%s",folder,file); // here wrote into temp the location as folder/file
_tprintf(L"The file name is: %s\n",temp);
HANDLE f;
WIN32_FIND_DATA data;
f=FindFirstFile(temp,&data);
if(f==INVALID_HANDLE_VALUE){
_tprintf(L"not found\n");
}
else{
_tprintf(L"found this file: %s\n",data.cFileName);
while(FindNextFile(f,&data)){
_tprintf(L"found this file: %s\n",data.cFileName);
}
FindClose(f);
}
_stprintf(temp,L"%s\\*",folder); // "d:\*" for example
_tprintf(L"Now, here are the folders:\n");
f=FindFirstFile(temp,&data);
TCHAR temp2[1000];
if(f==INVALID_HANDLE_VALUE){
_tprintf(L"not found\n");
}
else{
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
//_tprintf(L"found this directory: %s\n",data.cFileName);
_stprintf(temp2,L"%s\\%s",folder,data.cFileName);
SearchForFile(temp2,file);
}
while(FindNextFile(f,&data)){// _tprintf(L"%d %d\n",data.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY);
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
// _tprintf(L"found this directory: %s\n",data.cFileName);
{
_stprintf(temp2,L"%s\\%s",folder,data.cFileName);
SearchForFile(temp2,file);
}
}
FindClose(f);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SearchForFile(L"d:\\test", L"*Test*");
return 0;
}
You have to filter out the . and .. pseudo-folders found in every folder.
Roughly, in your recursive branch:
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
&& data.data.cFileName != "."
&& data.data.cFileName != "..")
In general, you should skip "." and ".." directories, they are synonyms for "current" and "parent" directory.
Pretty much no matter how you find the contents of a directory on Windows the first matches will be '.' (the current directory) and '..' (the parent directory). You probably want to ignore both of them.
Usually you explicitly test for and skip the "." and ".." subdirectories that are present in all directories (but the root). The code you're using searches subdirectories recursively, and since you're not ignoring the ".." directory, it'll search that, which will eventually lead to the root directory, and search all subdirectories from there -- meaning it'll search the whole disk.

Xcode & passing command line arguments

I just started working with C & Xcode and I've run into a little difficulty.
All I want to do is read a file from the command line and see the output in the terminal.
I think my problem lies with the path to the file that I want to read in. I'm using a Mac and the file is on my desktop, so the path should be Users/myName/Desktop/words.txt. Is this correct?
This is my code:
#import <Foundation/Foundation.h>
int main (int argc, const char* argv[]){
if(argc == 1){
NSLog(#" you must pass at least one arguement");
return 1;
}
NSLog(#"russ");
FILE* wordFile = fopen(argv[1] , "r");
char word[100];
while (fgets(word,100,wordFile)) {
NSLog(#" %s is %d chars long", word,strlen(word));
}
fclose(wordFile);
return 0;
}//main
If you need the path to a file in OS X, an easy way to get it is to just drag the file into the Terminal.app window where you are typing the command. Voila!
The path to the desktop is /Users/[username]/Desktop/
~/Desktop/ is a user-agnostic way of denoting this, ~ represents the current users home directory. It must be expanded using a method like stringByExpandingTildeInPath
Not sure about using C# (I've never used it on Mac OS X), but in Objective-C/Cocoa, you would do..
// Get array with first index being path to desktop
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
// Get the first element
NSString *desktopPath = [paths objectAtIndex:0];
// Append words.txt to path
NSString *theFilePath = [desktopPath stringByAppendingPathComponent:#"words.txt"];
NSLog(#"%#", theFilePath);
This is the most robust way of getting the Desktop path, as a user could technically move their Desktop folder else where (although this is pretty unlikely). Another valid option is to use the NSString method stringByExpandingTildeInPath:
NSString *desktop = [#"~/Desktop" stringByExpandingTildeInPath];
NSString *theFile = [desktop stringByAppendingPathComponent:#"words.txt"]
As I said, both those are in Objective-C, but it shouldn't be hard to translate to C#, assuming you can get at the Cocoa libraries.
The code you posted works correctly:
dbr:.../build/Debug $ ./yourcode ~/Desktop/words.txt
yourcode[2106:903] russ
yourcode[2106:903] this is words.txt is 17 chars long
Your terminal automatically expands the ~/ tilda path
Close... it's
/{Volume}/Users/myName/Desktop/words.txt
... where {Volume} is the name of your hard drive. You can also try using:
~/Desktop/words.txt
... where ~ is understood to mean "your home directory", but this might not resolve correctly.
(Note - this appears to be a C question, not a C# question)
Actually, you can do:
/Users/myName/Desktop/words.txt
You don't have to give the path to the volume.
However, to get the full path in C you'd do something like:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *home, *fullPath;
home = getenv("HOME");
fullPath = strcat(home, "/Desktop/words.txt");
The issue you're running into with passing the filename as an argument is that you need to set the current working directory to the place where the file exists.

Resources