Why rename () doesn't work?

I made an project called Py2Pyw. I made it secure, for other users (or crackers). The code works, I get no exception (if file exist, is .py ...), but when I'm going to rename, nothing happens. What it can be?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  #include <iostream> //Error handling
#include <fstream> //Check if file exists;
#include <cstdio> //File renaming
/* I've created strlen for less size (header functions that I don't need)*/



int strlen(char* var)
{
    int length;
    for(length = 0; var[length] != '\0'; length++);
    return length;
}

int main(int argc, char* argv [])
{   //Check for errors

    if(argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " python_file_or_path_and_file.py";
        return 1;
    }

        /* MAIN CODE */
        try
        {
            //Check extension, but don't use too much memory (dynamic allocation
            const int length = strlen(argv[1]);
            char* py_ext = new char[3];
            for(int i = 0; i < 3; i++ )
            {
                int lg = length - i;
                py_ext[2 - i] = argv[1][lg - 1];
            }
            if(py_ext[0] != '.' && py_ext[1] != 'p' && py_ext[2] != 'y')
            {
                throw 2;
            }
            //Check if file exists
            std::ifstream pyfile;
            pyfile.open(argv[1]);
            if(!pyfile.good() || pyfile.bad())
            {
                pyfile.close();
                throw 3;
            }
            char ext[length + 1];
            for(int i = 0; i < length; i++)
            {
                ext[i] = argv[1][i];
            }
            ext[length] = 'w';
            rename(reinterpret_cast<const char*>(argv[1]), reinterpret_cast<const char*>(ext));
        }
        catch(int e)
        {
            if(e == 2)
            {
                std::cerr << "The extension is not for a .py file";
            }
            if(e == 3)
            {
                std::cerr << "The expecified file don't exist or is damaged.";
                return e;
            }
        }
    }
Last edited on
It doesn't work because your program still has the file open when you try to rename it.
Oh, it wil only close when file doesn't exists... Thank
you, I'll try to make it work.
iQChange wrote:
Oh, it wil only close when file doesn't exists...
This doesn't make sense either - if you fail to pull the lid off a jar, how do you intend to put the lid back on?
> It doesn't work because your program still has the file open when you try to rename it.
system dependant

@OP:
> but when I'm going to rename, nothing happens
check errno to know what went wrong
by the way `ext' is not zero terminated.

> Check extension, but don't use too much memory (dynamic allocation)
dynamic allocation is not free

> char ext[length + 1];
illegal, size must be constant
Last edited on
So what should I do? On debug, I saw that ext value is [code]file.py&7[code], or almost that.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <fstream>
#include <string>
#include <cstdio>
#include <iostream>

bool exists( const char* path ) { return std::ifstream(path) ; }

bool ends_with( const std::string& str, const std::string& tail )
{
    return str.size() >= tail.size() &&
           str.rfind(tail) == str.size() -  tail.size() ;
}

int main( int argc, char* argv[] )
{
    if( argc != 2 ) { /* appropriate message */ return 1 ; }

    if( !ends_with( argv[1], ".py" ) ) { /* appropriate message */ return 2 ; }

    if( !exists( argv[1] ) ) { /* appropriate message */ return 3 ; }

    const std::string namew = std::string( argv[1] ) + 'w' ;
    if( std::rename( argv[1], namew.c_str() ) != 0 ) { /* appropriate message */ return 4 ; }
}
Ok, I fixed it myself (allocated the memory, deleted unnecessary variables) and all. Now, I have another question (my problem is already fixed, answer if you know how):
How can I drag-and-drop my exe on .py files? Every time I do it, the Python Shell is called, and my program don't even runs.
Have you tried the other way around? Dropping the .py file on the .exe file?
@Peter87 God, I'm a IDIOT! Hahahaha, I can't believe it! Thank you so much!
Ok, finished and even more secure now. But my question is different.
How can I deal my project for Linux and Mac? I'm on Windows and my compiler is MinGW.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream> //Error handling
#include <fstream> //Check if file exists
#include <cstdio> //File renaming
#include <new>
/* I've created some functions for less size (header functions that I don't need) and security (type to type, not type* to type[] and others)*/

int strlen(const char* var)
{
    int length;
    for(length = 0; var[length] != '\0'; length++);
    return length;
}
//Security checking for argv and py_ext
bool str_is_equal(const char* str_a_, const char* str_b_)
{
    char* str_b = const_cast<char*>(str_b_);
    char* str_a = const_cast<char*>(str_a_);
    int a_len = strlen(str_a);
    int b_len = strlen(str_b);
    if(a_len != b_len) return false;
    int check = 0;
    for(; check <= a_len; check++)
    {
        if(str_a[check] != str_b[check])
        {
            return false;
        }
    }
    return true;
}

//Main Project
int main(int argc, char* argv [])
{
    //Check for errors
    if(argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " python_file_or_path_and_file.py\nFor help, type in your console: Py2Pyw.exe -help" << std::endl;
        std::cout << "Enter anything to proceed (exit)... ";
        int nl;
        fflush(stdout);
        do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
    }


        /* MAIN CODE */
        try
        {
            const int length = strlen(argv[1]);
            char * ext = new char[length + 1];
            char* py_ext = new char[3];
            if(str_is_equal(argv[1],"-help"))
            {
                std::cout << "Py2Pyw is a C++ based application for Python programmers. It's open source, simple, secure (cracking or file-damaging), lightweght , single-file and cross-platform! It removes the annoying console from your GUI applications, running them with the pythow.exe program, that comes with your interpreter. Feel free to use!\n\nThe usage is: " << argv[0] << "python_file_or_path_and_file.py" << std::endl;
                std::cout << "Enter anything to proceed (exit)... ";
                int nl;
                fflush(stdout);
                do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
                return 0;
            }

            for(int i = 0; i < 3; i++ )
            {
                int lg = length - i;
                py_ext[2 - i] = argv[1][lg - 1];
            }
            if(!str_is_equal(py_ext,".py"))
            {
                throw 2;
            }

            //Deallocate py_ext memory.
            delete[] py_ext;
            //Check if file exists
            std::ifstream pyfile;
            pyfile.open(argv[1]);
            if(!pyfile.good() || pyfile.bad())
            {
                pyfile.close();
                throw 3;
            }
            pyfile.close();

            //No exceptions, can proceed.
            for(int i = 0; i < length; i++)
            {
                ext[i] = argv[1][i];
            }
            ext[length] = 'w';
            ext[length + 1] = '\0';
            rename(reinterpret_cast<const char*>(argv[1]), reinterpret_cast<const char*>(ext));
            //Dealocate memory
            delete[] ext;
            //Check if it's all Ok with file
            pyfile.open(ext);
            if(!pyfile.good() || pyfile.bad())
            {
                throw 4;
            }

            std::cout << "Program success.\nFile " << argv[1] << " won't show console. Search for " << ext <<"\nEnter anything to proceed (exit)... ";
            int nl;
            fflush(stdout);
            do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
            return 0;

        }
        catch(int e)
        {
            if(e == 2)
            {
                std::cerr << "The file is not a .py or you've entered an mistaken parameter." << std::endl;
                std::cout << "Enter anything to proceed (exit)... ";
                int nl;
                fflush(stdout);
                do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
                return e;
            }

            if(e == 3)
            {
                std::cerr << "The expecified file don't exist ,is damaged or is being bused by another process." << std::endl;
                std::cout << "Enter anything to proceed (exit)... ";
                int nl;
                fflush(stdout);
                do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
                return e;
            }
            if(e == 4)
            {
                std::cerr << "Error with file creating (" << argv[1] << "w). Damaged-file. Source is safe.\nEnter anything to proceed (exit)... ";
                int nl;
                fflush(stdout);
                do nl = getchar(); while ((nl != '\n') &&( nl != EOF)) ;
                return e;
            }
        }
        catch(std::bad_alloc& bad_allocation)
        {
            std::cerr << "No memory avaible! See an computer technician and show the log named \"out_of_memory.log\"" << std::endl;
            std::ofstream log;
            log.open("out_of_memory.log");
            log << "Program" << argv[0] << "throwed an instance of ";
            log << bad_allocation.what();
            log << "When\n\nTrying allocate " << sizeof(char)*3 << "bytes in variable 'py_ext'.\n";
            log << "\nTrying allocate " << (sizeof(char)*strlen(argv[1]))+1 << "on variable 'ext'";
            std::cout << "Enter anything to proceed (exit)... ";
            int nl;
            fflush(stdout);
            do nl=getchar(); while ((nl!='\n') && (nl!=EOF));
            return 5;
        }
    }

> How can I deal my project for Linux and Mac?
distribute the source code

> I've created some functions for less size (header functions that I don't need)
http://linux.die.net/man/1/nm

> and security (type to type, not type* to type[] and others)
no idea what you're talking about

> char* str_b = const_cast<char*>(str_b_);
¿what for?

> char * ext = new char[length + 1];
> ext[length + 1] = '\0';
out of bounds

> Check if file exists
http://www.cplusplus.com/forum/general/71333/#msg380507

> Enter anything to proceed (exit)...
I consider that a bad UI


by the way
$ mv foo.py{,w}
@ne555

> How can I deal my project for Linux and Mac?
distribute the source code

And how Python programmers will compile it?


> I've created some functions for less size (header functions that I don't need)
http://linux.die.net/man/1/nm

I saw the link, but, anyway, these functions didn't killed me.

(#str)

> and security (type to type, not type* to type[] and others)
no idea what you're talking about

I was talking about the function bool str_is_equal. Think: what is the default type when passing strings to a function? const char[]. If I just use a char*, your compiler warn you:
warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]



> char* str_b = const_cast<char*>(str_b_);
¿what for?

#str


> char * ext = new char[length + 1];
> ext[length + 1] = '\0';
out of bounds
WHY? Null-terminated string. http://en.wikipedia.org/wiki/Null-terminated_string


> Check if file exists
http://www.cplusplus.com/forum/general/71333/#msg380507

[IDIOT QUESTION (but I don't know the answer, never used <sys>)] It's OS dependent?


> Enter anything to proceed (exit)...
I consider that a bad UI

I know it
:(
. Any idea?


by the way
$ mv foo.py{,w}

Yes, but train with real things can make you learn others.
Last edited on
> And how Python programmers will compile it?

I wonder how you think the Python interpreter is run on different platforms. Not only that, but Python can interface with C (and the most popular interpreter is itself written in C).
@L B Yes, but I don't have the compilers (as @ne555 said). Sorry if I didn't understood (I don't speak english).
C++ is "write once, compile anywhere", whereas Java is "compile once, run anywhere". To allow your program to be run on other platforms, either you must compile it for every platform (which is how Python and the JVM work), or you can simply release the source code and let people compile it themselves.

So, the fact that you are concerned about Python programmers being able to use your program is confusing - what does Python have to do with compiling your code?
> And how Python programmers will compile it?
$ g++ foo.cpp -O2 -o Py2Pyw
# cp Py2Pyw /usr/bin/
put that in a makefile if you want.
signal g++ as a make dependency.

I don't know where Mac stores the executables


> Think: what is the default type when passing strings to a function? const char[].
> If I just use a char*, your compiler warn you:
1
2
int strcmp ( const char * str1, const char * str2 );[
size_t strlen ( const char * str );
¡look, const char*!
there was no need for you to create such functions.

>>> char* str_b = const_cast<char*>(str_b_);
>>¿what for?
> #str
that cast was completely unnecessary, ¿what did it allowed to do?

> WHY? Null-terminated string. http://en.wikipedia.org/wiki/Null-terminated_string
when you create an array, the number between the brackets indicates the size of the array.
in C/C++ the indexing starts in 0 and so ends in `size-1'
trying to access the position `size' is an out of bounds error

From your link: ``A common bug was to not allocate the additional space for the NUL, so it was written over adjacent memory''


`stat()' conforms to POSIX, so yep system dependent.


I like my programs to terminate when they are done, so would just remove the whole thing.


just saying that there is already an incredible easy way to do the renaming.
Last edited on
@ne555 Yep, I know that project is useless :(.


> Think: what is the default type when passing strings to a function? const char[].
> If I just use a char*, your compiler warn you:
int strcmp ( const char * str1, const char * str2 );[
size_t strlen ( const char * str );
¡look, const char*!
there was no need for you to create such functions.

Yes, a const char array can be shown as const char*, I know.

So there is no way to release any project for any system without downloading an compiler? I have not the Linux ( || Mac) compiler. Didn't found gcc for Mac on page, and Linux gcc folder isn't built. What should I do? I'm sorry for that issues, but try understand: I'm twelve, and I program since 2010.
Last edited on
You most likely found the source instead of the binaries. Building a compiler from source is a very difficult task.

Generally, you can 'release' a program by building it in release mode and distributing the executable. If you only build it for Windows, then people will just have to use Windows to run it. If you build it on Windows, and then also build it on Linux, you can distribute both as separate download links.

Look at the download pages for various software and notice the options for Windows, Linux, Mac, etc.

Releasing the source code is good for 'advanced users' for whom the provided download links are no good.
Last edited on
Topic archived. No new replies allowed.