How to make your program copy itself into another folder? - c

I know this sounds like a dumb question, but I'm new to programming and I just want to place my program into the start up folder whenever someone runs it.
For example: End user runs my application --> My application copies itself into their start up folder (or moves itself)
I'm using C to write this application, and it would be great if you guys can refer me to a function that will allow me to do this (preferably a WinAPI function, but it doesn't really matter).
Thank you, all help is appreciated.

I would probably write the essential parts of this into a separate function, but here are the basics:
Using Windows (per WinAPI reference in post)...
#include <ansi_c.h>
#include <windows.h>
int main(void)
{
char filename[ MAX_PATH ];
char newLocation[]="C:\\enterstartupdirhere";//put actual path here (i.e. don't use as is)
BOOL stats=0;
DWORD size = GetModuleFileNameA( NULL, filename, MAX_PATH );
if (size)
CopyFile(filename, newLocation, stats);
else
printf("Could not find EXE file name.\n");
return 0;
}

Related

How do I read a file, take the file content (which is just simple characters) and put them in a variable to compare?

So I have an assignment for hs and honestly I do not know how to program in C so I would appreciate all the help I can get.
Anyways my problem is that I cannot for the life of me read a content of a file, asign it to a variable and compare it to another variable if the content is the same.
I am making a login interface with already pre-input admin email and admin password and here is my mess of a code for now:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *emailf;
emailf = fopen("email.txt", "r");
char* fgets(char* emailx){
return emailx;
}
fclose(emailf);
char email [30];
char password [16];
do{
printf("E-mail:");
scanf("%c", &email);
}
while (email != emailx);
What it does is tells me that emailx variable is not even declared so if you could help me I would be glad! And also it does not have to resemble this code since I do not know jack crap about C programming language so if you could tell me a different way to try what I am trying would be good as well. Thank you!
There are several things that are not good in your program.
Firstable, are you sure you are openning properly the file "email.txt" ?
Then, this part of the code is wrong, you cannot define a function inside a function, especially if this function already exist in a library:
char* fgets(char* emailx){
return emailx;
}
maybe you should try something like
emailx = fgets(emailx);
But first you should declare your variable.
I ve never used those functions so I don t know how it works precisely, but chek the manual.

Creating directories based off variable names

I have been creating a C program that is going to pull a range of data from excel and store it in variables. My question, how do i create a directory in C that uses variables. I have tried several ways yesterday while at work.
#include <stdio.h>
int main(void)
{
//creating directory (works)
system("md E:\sub_directory");
system("mkdir E:\\sub_dir2");
//trying to create directory based off variables (not working yet)
char CustName[50] = "Mars";
char Product[50] = "Chocolate Drops";
int JobNumber = 100;
system("md E:\\",JobNumber,CustName,Product"",JobNumber,CustName,Product);
system("md E:\\%04i %s %s",JobNumber,CustName,Product);
return 0;
}
As you can see above, this is the code that i finished up with. The first section was just a reference point so i know base command structure. I then proceeded to fiddle with formatting that i currently know which didnt work.
Would anyone be able to shed some light on how i would use variables name to create the directories? (im currently working on a windows 10 machine but the program is going to be run on a windows 7 machine. I dont know if this changes anything.
You should use sprintf to create one string with the complete pathname you want to create. Then you should use the mkdir function of the standard library to create the directory.
Note that to create a directory, all component paths must exist, so to create E:\my\path you may first need to create E:\my and then E:\my\path.
I have had a look at sprintf and i think i understand it. i have the following code:
char CustName[50] = "Mars";
char Product[50] = "Chocolate Drops";
int JobNumber = 100;
char *filepath[100];
sprintf(*filepath, "mkdir D:\\%04i %s %s", JobNumber, CustName, Product);
puts(*filepath);
sorry if this isnt the correct use, i am still pritty new to programming

Mac sandbox: running a binary tool that needs /tmp

I have a sandboxed Cocoa app that, during an export process, needs to run a third party command-line tool. This tool appears to be hardcoded to use /tmp for its temporary files; sandboxing doesn't permit access to this folder, so the export fails.
How can I get this tool to run? I don't have access to its source code, so I can't modify it to use NSTemporaryDirectory(), and it doesn't appear to respect the TMP or TEMPDIR environment variables. For reasons I don't understand, giving myself a com.apple.security.temporary-exception.files.absolute-path.read-write entitlement doesn't seem to work, either.
Is there some way to re-map folders within my sandbox? Is there some obscure trick I can use? Should I try to patch the tool's binary somehow? I'm at my wit's end here.
I was able to get user3159253's DYLD_INSERT_LIBRARIES approach to work. I'm hoping they will write an answer describing how that works, so I'll leave the details of that out and explain the parts that ended up being specific to this case.
Thanks to LLDB, elbow grease, and not a little help from Hopper, I was able to determine that the third-party tool used mkstemp() to generate its temporary file names, and some calls (not all) used a fixed template starting with /tmp. I then wrote a libtmphack.dylib that intercepted calls to mkstemp() and modified the parameters before calling the standard library version.
Since mkstemp() takes a pointer to a preallocated buffer, I didn't feel like I could rewrite a path starting with a short string like "/tmp" to the very long string needed to get to the Caches folder inside the sandbox. Instead, I opted to create a symlink to it called "$tmp" in the current working directory. This could break if the tool chdir()'d at an inopportune time, but fortunately it doesn't seem to do that.
Here's my code:
//
// libtmphack.c
// Typesetter
//
// Created by Brent Royal-Gordon on 8/27/14.
// Copyright (c) 2014 Groundbreaking Software. This file is MIT licensed.
//
#include "libtmphack.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
//#include <errno.h>
#include <string.h>
static int gbs_has_prefix(char * needle, char * haystack) {
return strncmp(needle, haystack, strlen(needle)) == 0;
}
int mkstemp(char *template) {
static int (*original_mkstemp)(char * template) = NULL;
if(!original_mkstemp) {
original_mkstemp = dlsym(RTLD_NEXT, "mkstemp");
}
if(gbs_has_prefix("/tmp", template)) {
printf("libtmphack: rewrote mkstemp(\"%s\") ", template);
template[0] = '$';
printf("to mkstemp(\"%s\")\n", template);
// If this isn't successful, we'll presume it's because it's already been made
symlink(getenv("TEMP"), "$tmp");
int ret = original_mkstemp(template);
// Can't do this, the caller needs to be able to open the file
// int retErrno = errno;
// unlink("$tmp");
// errno = retErrno;
return ret;
}
else {
printf("libtmphack: OK with mkstemp(\"%s\")\n", template);
return original_mkstemp(template);
}
}
Very quick and dirty, but it works like a charm.
Since #BrentRoyal-Gordon has already published a working solution I'm simply duplicating my comment which inspired him to produce the solution:
In order to fix a program behavior, I would intercept and override some system calls with the help of DYLD_INSERT_LIBRARIES and a custom shared library with a custom implementation of the given system calls.
The exact list of the syscalls which need to be overridden depends on nature of the application and can be studied with a number of tools built upon MacOS DTrace kernel facility. E.g. dtruss or Hopper. #BrentRoyal-Gordon has investigated that the app can be fixed solely with an /appropriate/ implementation of mkstemp.
That's it. I'm still not sure that I've deserved the bounty :)
Another solution would be to use chroot within the child process (or posix_spawn options) to change its root directory to a directory that is within your sandbox. Its “/tmp” will then be a “tmp” directory within that directory.

program doesnt work if called from another folder

In Command Prompt, this works: whatever\folder> bezier.exe
but this doesn't: whatever> folder\bezier.exe
My bezier program loads some settings from a local file, so I believe the problem is that the program thinks its directory is whatever\ when it is actually whatever\folder\. I'm calling it from within a C program using CreateProcess(). If I am correct in guessing the problem, is there any way to ensure the program has the right directory for itself?
the main method of bezier.exe:
int main(int argc, char* argv[]) {
char buf[200];
FILE* f = fopen("out.txt","w");
GetCurrentDirectory(200,buf);
fprintf(f,buf);
fclose(f);
SDL_Surface* screen;
SDL_Event e;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_FULLSCREEN|SDL_HWSURFACE);
if (screen == NULL)
exit(-1);
SDL_ShowCursor(SDL_DISABLE);
srand(time(NULL));
loadColors(COLOR_FILE);
fill(screen, backColor);
initialiseVars();
while (e.type != SDL_KEYDOWN)
{
//do stuff
}
SDL_Quit();
return 0;
}
Here's the crazy part. With "..> folder\bezier.exe" it doesn't write its path, but it does start a new window. That doesn't make any sense to me, because SDL_SetVideoMode is after writing the path.
You can use GetModuleHandle and GetModuleFileName to find out where your execuatble file is, then use that information to create a file specification for your local settings file.
GetModuleHandle with a NULL argument will give you the handle for the current executable. Then, passing that to GetModuleFileName will give you the fully qualified name of that executable. Just strip off the executable filename from the end and add your configuration file name.
However, that's been a bad idea for a long time now, since Windows provides per-application and per-user settings areas for this sort of stuff - you can generally get those locations with SHGetFolderLocation() and its brethren.
Use the first method only if this is for a personal project. If you plan to release your software to the wild, you should separate executable and configuration information as per Microsoft guidelines.
Regardless of that, it appears you now have the problem that you think the file is not being written to. You need to check that. When you open that file out.txt for write, it does so in the current directory. If you're running in the parent directory (with folder\bezier.exe), it will create it in the parent directory and looking for it in the folder directory is a waste of time.
If you are looking in the directory where you're running the program from, and it's still not being created, there are possible reasons for this. For a start, you should check (ie, capture and output) the return codes from all those f* functions, fopen, fprintf and fclose.

How to use chroot function in C programming?

I know that use the command "chroot" in linux need some files or directories such as usr, bin and so on. But when I use the function chroot() in C, do I need these files?
Here is my code, which "hw.out" is a binary file which just print "Hello, world". I compiled it and run it as root, but it was failed to print "Hello, world". What else should I do? Thank you!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int result = chroot(".");
if(result == 0)
printf("Chroot Succese.\n");
char *arrays[]={"./hw.out",NULL};
execvp("./hw.out", arrays);
return 0;
}
execvp is most likely failing, probably with ENOENT: no such file or directory, if hw.out is a dynamically linked executable.
For that to work, all the libraries required by hw.out need to be findable in the chrooted environment.
Try linking hw.out statically, and it should work. (And add error checking after execvp to see what errno is set to after the call if it returns.)
Please test that your hw.out works with command line chroot.
Perhaps hw.out is dynamically linked and is missing some libraries or ld-linux.so in the chroot directory.
Nitpicks 1, what's the point of return 0 after execvp? it never gets executed unless there is an error. I would rather have perror("can't exec"); return 1;
Nitpick 2, chroot() doesn't change working directory, although it works in your case, as you are chrooting to ".", it won't work as you expect if you later change it to chroot("somedir").
Make sure that hw.out is in the correct direct. Perhaps it is easier to have it statically linked if it is using libraries. Otherwise need to enable after chroot that it can access the dynamic libraries.

Resources