Page 1 of 1

Random File and URL Opener

Posted: Mon Apr 04, 2016 1:11 am
by ~
filesopen Minimum_minutes_random_delay Maximum_minutes_random_delay Database_name Database_configuration_row_number

Here I have a console program I wrote that randomly and automatically opens local files or URLs taken from an SQLite3 database which it handles by itself using the SQLite3 Amalgamation library.

It's fully written in C and works under Windows so far (maybe it can work under Wine too).

Here is the compiled binary:
FILESOPEN.EXE

Here you can see and learn how I wrote the C code to handle the SQLite3 code from C:
>> Text Recording for the Random File Opener <<
Image

The documented structure and usage of the databases is contained in the text recording.

You can test the program with the following database which contains more than 2 million domain names from the daily top 1 million from Alexa:
domains_alexaranks.db


To run the program you just need the following command:

Code: Select all

filesopen 1 1 domains_alexaranks.db 1


filesopen minimum_minutes_random_delay maximum_minutes_random_delay database_name database_configuration_row_number

This is the main source code (compiled using MinGW GCC):

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "SQLite3-Amalgamation-3.12.0/sqlite3.h"
#include "SQLite3-Amalgamation-3.12.0/sqlite3.c"
#include "SQLite3-Amalgamation-3.12.0/sqlite3ext.h"
#include <windows.h>
#include <time.h>

const char sqlite3_version[] = SQLITE_VERSION;


//Some custom function declarations:
///
 unsigned long moreRandomFactor=1;
 unsigned long long_getNumBits(unsigned long num);
 unsigned long stringSum(char *str, unsigned int str_SZ);
 unsigned long getDateMilliseconds(void);
 unsigned long stringToRandomNumber(char *str, unsigned int str_SZ, unsigned long max_rand, unsigned long toRet);



//Set default values for the number of table rows and for the current column
//this last one will be selected at random:
///
 int SQLite3_Row_Ctr=1;
 int SQLite3_Current_Row=1;

 sqlite3      *SQLite3_DB_Obj;
 sqlite3_stmt *SQLite3_State;
 int           SQLite3_DB_Res_Handle;
 char         *SQL_String;
 char         *SQLite3_ErrorMsg=NULL;
 char         *SQLite3_zTail_String;



//These are the default minimum and maximum number of minutes to wait
//before trying to open other file/directory entry:
///
 int minwait=1;
 int maxwait=1;


long minmax_rand(long min, long max)
{
 return rand()%((max+1) - min) + min;
}


char *config_tablename;
char *config_datarowname;
char *config_idrowname;
char *config_fileprotocol;
char *config_mainshell;
int   config_svfskip;
char *config_slashchar;


static int SQLite3_Callback_config(void *NotUsed, int argc, char **argv, char **azColName)
{
 config_tablename=malloc(512);
 config_datarowname=malloc(512);
 config_idrowname=malloc(512);
 config_fileprotocol=malloc(512);
 config_mainshell=malloc(512);
 config_slashchar=malloc(512);

 sprintf(config_tablename,"%s",argv[0]);
 sprintf(config_datarowname,"%s",argv[1]);
 sprintf(config_idrowname,"%s",argv[2]);
 sprintf(config_fileprotocol,"%s",argv[3]);
 sprintf(config_mainshell,"%s",argv[4]);
 config_svfskip=atoi(argv[5]);
 sprintf(config_slashchar,"%s",argv[6]);


 printf("Getting database configuration...\n");
 printf("tablename=%s\ndatarowname=%s\nidrowname=%s\nfileprotocol=%s\nmainshell=%s\nsvfskip=%d\nslashchar=%s\n\n", config_tablename, config_datarowname, config_idrowname, config_fileprotocol, config_mainshell, config_svfskip, config_slashchar);


 return 0;
}



static int SQLite3_Callback(void *NotUsed, int argc, char **argv, char **azColName)
{
 int x=0;
 int requiredSize=0;
 int   openstrlen=0;
 char *cmd=NULL;
 char *cmd2=NULL;
 char *openstr="open";
 char *openstrW;
 char *explorerstr=config_mainshell;
 char *explorerstrW;

 int   execres=0;

 openstrW=malloc(131072);
 explorerstrW=malloc(131072);
 cmd=malloc(131072);
 cmd2=malloc(131072);

 MultiByteToWideChar(
                     (UINT)CP_UTF8,
                     (DWORD)0,
                     (LPCSTR)explorerstr,
                     (int)-1,
                     (LPWSTR)explorerstrW,
                     (int)131072
                    );

 MultiByteToWideChar(
                     (UINT)CP_UTF8,
                     (DWORD)0,
                     (LPCSTR)openstr,
                     (int)-1,
                     (LPWSTR)openstrW,
                     (int)131072
                    );




 for(x=0; x<argc; x++)
 {
  snprintf(cmd,131072,"\"%s%s\"",config_fileprotocol,argv[x]+config_svfskip);
  
  //Try to increase the randomness of the selected row element:
  ///
   moreRandomFactor=stringToRandomNumber(cmd, 131072, SQLite3_Row_Ctr-1, moreRandomFactor);


/*
int MultiByteToWideChar(
  _In_      UINT   CodePage,
  _In_      DWORD  dwFlags,
  _In_      LPCSTR lpMultiByteStr,
  _In_      int    cbMultiByte,
  _Out_opt_ LPWSTR lpWideCharStr,
  _In_      int    cchWideChar
);
*/
  MultiByteToWideChar(
                      (UINT)CP_UTF8,
                      (DWORD)0,
                      (LPCSTR)cmd,
                      (int)-1,
                      (LPWSTR)cmd2,
                      (int)131072
                     );

  printf("%ld: %s\n\n", SQLite3_Current_Row, cmd);

/*
HINSTANCE ShellExecute(
  _In_opt_ HWND    hwnd,
  _In_opt_ LPCTSTR lpOperation,
  _In_     LPCTSTR lpFile,
  _In_opt_ LPCTSTR lpParameters,
  _In_opt_ LPCTSTR lpDirectory,
  _In_     INT     nShowCmd
);

*/

  execres=(int)ShellExecuteW(
                (HWND)0,
                (LPCWSTR)openstrW,
                (LPCWSTR)explorerstrW,
                (LPCWSTR)cmd2,
                (LPCWSTR)NULL,
                (INT)SW_SHOWNORMAL
               );


  switch(execres)
  {
   case 0:
   printf("exec: 0");
   break;

   case ERROR_BAD_FORMAT:
    printf("exec: ERROR_BAD_FORMAT");
   break;

   case SE_ERR_ACCESSDENIED:
    printf("exec: SE_ERR_ACCESSDENIED");
   break;

   case SE_ERR_ASSOCINCOMPLETE:
    printf("exec: SE_ERR_ASSOCINCOMPLETE");
   break;

   case SE_ERR_DDEBUSY:
    printf("exec: SE_ERR_DDEBUSY");
   break;

   case SE_ERR_DDEFAIL:
    printf("exec: SE_ERR_DDEFAIL");
   break;

   case SE_ERR_DDETIMEOUT:
    printf("exec: SE_ERR_DDETIMEOUT");
   break;

   case SE_ERR_DLLNOTFOUND:
    printf("exec: SE_ERR_DLLNOTFOUND");
   break;

   case SE_ERR_FNF:
    printf("exec: SE_ERR_FNF");
   break;

   case SE_ERR_NOASSOC:
    printf("exec: SE_ERR_NOASSOC");
   break;

   case SE_ERR_OOM:
    printf("exec: SE_ERR_OOM");
   break;

   case SE_ERR_SHARE:
    printf("exec: SE_ERR_SHARE");
   break;
  }


  sleep(60*(int)minmax_rand(minwait,maxwait));
 }




 free(cmd);
 free(cmd2);
 free(openstrW);
 free(explorerstrW);


 return 0;
}


static int SQLite3_Callback2(void *NotUsed, int argc, char **argv, char **azColName)
{
 SQLite3_Row_Ctr=atol(argv[0]);
 return SQLite3_Row_Ctr;
}



void clear_state()
{
 //NOTE: This is for the good practice of not leaving
 //      freeing of resources or other default operations
 //      at their default state but accelerate and ensure
 //      the global sanity of the environment and the program
 //      by specifying every operation exactly as we want it:
 ///
 sqlite3_finalize(SQLite3_State); 
 sqlite3_close(SQLite3_DB_Obj);
 free(SQL_String);

}






int main(int argc, char *argv[])
{
 atexit(clear_state);
 SQL_String=malloc(4096);



 if(argc>=5)
 {
  if(!(minwait=atoi(argv[1])))minwait=1;
  if(!(maxwait=atoi(argv[2])))maxwait=1;
 }
  else
  {
   printf("Usage: filesopen min_minutes max_minutes SQLITE3_Database_Path Database_Config_ID\n\n");
   return -2;
  }


 //Open the database and see if it was successful. If not, just exit the program:
 ///
  SQLite3_DB_Res_Handle=sqlite3_open(argv[3], &SQLite3_DB_Obj);

  if(SQLite3_DB_Res_Handle!=SQLITE_OK)
  {
   printf("Error opening database\n\n");
   return -1;
  }


  //Get the configuration of the database to use the proper table and field names,
  //as well as basic formatting for the data:
  ///
   snprintf(SQL_String, 4096, "SELECT tablename,datarowname,idrowname,fileprotocol,mainshell,svfskip,slashchar FROM config WHERE configid=%s LIMIT 1", argv[4]);
   SQLite3_DB_Res_Handle=sqlite3_exec(
                                      SQLite3_DB_Obj,
                                      SQL_String,
                                      SQLite3_Callback_config,
                                      SQLite3_zTail_String,
                                      &SQLite3_ErrorMsg
                                     );







 //Get all columns for the first time to count them.
 //Its callback will return the count in SQLite3_Row_Ctr:
 ///
  snprintf(SQL_String, 4096, "SELECT COALESCE(MAX(%s)+1, 0) FROM %s", config_idrowname, config_tablename);
  SQLite3_DB_Res_Handle=sqlite3_exec(
                                     SQLite3_DB_Obj,
                                     SQL_String,
                                     SQLite3_Callback2,
                                     SQLite3_zTail_String,
                                     &SQLite3_ErrorMsg
                                    );

 printf("Cycling through %ld files...\n", SQLite3_Row_Ctr-1);



 while(1)
 {
  //Go to next row (selected randomly):
  ///
   SQLite3_Current_Row=moreRandomFactor;


  //Get random files to open:
  ///
   snprintf(SQL_String, 4096, "SELECT %s FROM %s WHERE %s=%ld LIMIT 1", config_datarowname, config_tablename, config_idrowname, SQLite3_Current_Row);
   SQLite3_DB_Res_Handle=sqlite3_exec(
                                      SQLite3_DB_Obj,
                                      SQL_String,
                                      SQLite3_Callback,
                                      SQLite3_zTail_String,
                                      &SQLite3_ErrorMsg
                                     );


  //If there was a database error or fault, just end:
  ///
   if(SQLite3_ErrorMsg)return 0;
 }


 return 0;
}



unsigned long long_getNumBits(unsigned long num)
{
 unsigned long toRet=0;
 while(num)
 {
  num>>=1;
  toRet++;
 }

 return toRet;
}



unsigned long stringSum(char *str, unsigned int str_SZ)
{
 int x=0;
 unsigned long toRet=0;
 for(x=0; x<str_SZ; x++)
 {
  toRet+=x;
  toRet+=(int)str[x];
 }


 return toRet;
}


unsigned long getDateMilliseconds(void)
{
 return clock();
}



unsigned long stringToRandomNumber(char *str, unsigned int str_SZ, unsigned long max_rand, unsigned long toRet)
{
 unsigned long x=0;
 toRet+=minmax_rand(1, max_rand);


 for(x=0; x<str_SZ; x++)
 {
  toRet+=x;
  toRet+=getDateMilliseconds();
  toRet+=(unsigned long)str[x];
  if(toRet>max_rand)toRet&=minmax_rand(1, max_rand);
 }

 if(toRet==0)toRet++;
 return toRet;
}


Re: Random File and URL Opener

Posted: Mon Apr 04, 2016 8:56 pm
by FallenAvatar
Who would ever want to do anything like this???

On top of that, commented out code that isn't used, zero comments of what is going on, pure laziness on your part of learning Win32 (Why the heck are you calling a function to convert a normal string to a wide string instead of just adding a L in front of the string declaration, such as L"₣ṺḈḰẙṓṹ") and a complete lack of caring when it comes to memory usage.

Yea, please post this puss elsewhere...

- Monk

Re: Random File and URL Opener

Posted: Tue Apr 05, 2016 12:23 am
by ~
tjmonk15 wrote:Who would ever want to do anything like this???

On top of that, commented out code that isn't used, zero comments of what is going on, pure laziness on your part of learning Win32 (Why the heck are you calling a function to convert a normal string to a wide string instead of just adding a L in front of the string declaration, such as L"₣ṺḈḰẙṓṹ") and a complete lack of caring when it comes to memory usage.

Yea, please post this puss elsewhere...

- Monk
Please tell me exactly what you didn't understand so I can add further explanations that can be followed in a paced and structured text recording and code snippets.

Practically all strings come from the database. The file name is UTF-8 and needs to be UTF-16 for the WinAPI. The name of the shell also comes from a "config" table from the specified database. It's probably cleaner or even correct converting them in real time than using something like (L(string_pointer)).

The reason for the program is that if you have thousands of files or URLs, you might want to visit them frequently to feed your brain and senses with new information, so it's for a human reason (content that would otherwise get you tired to open manually by the time you started to review such material).

I also plan to implement some sort of crawler based on a task like this, or being able to open and handle Unicode file names from PHP by writing a module.

I just used multiline comments to show the WinAPI function headers/declarations so as to make them much clearer (I haven't found a clearer method after several years of looking at WinAPI code calls).

I don't think that using L"String" would work if I want to encode and convert an UTF-8 string to UTF-16 one like "D:\\[追寻记忆的痕迹].In.Search.of.Memory.2007.CHS.Scan-UNKNOWN.pdf". I need it to get encoded exactly as it is in the file system and the functions I used were the only ones that allowed me to achieve being able to open those files named in such a way without having to rename them manually with regular characters only. Remember how difficult and problematic it is being able to open strangely-named files from C/GCC/MinGW if you don't use the WinAPI file/process launching, and most likely, string encoding functions.

That string is being passed as a pure binary string of 8-bit byte characters from SQLite3 to the C program.

I would always need to implement my own functions in Assembly, C or JavaScript to handle Unicode instead of a simple "automagic" L that I don't know what really does anyway, so I just started the snippet with what I could.


Also I added the following randomizing function which seems to improve randomness a lot over the standard rand() which seemed to always follow the same basic sequence of chosen files. Now this function adds together the values of the latest used strings as in a checksum, adds a standard rand(), the current time, the value of the loop variable and then ensures again that the random number is within the range but using AND to complete the randomness in range:

Code: Select all

unsigned long stringToRandomNumber(char *str, unsigned int str_SZ, unsigned long min_rand, unsigned long max_rand, unsigned long toRet)
{
 unsigned long x=0;

 toRet+=(rand()%((max_rand+1) - min_rand) + min_rand);


 for(x=0; x<str_SZ; x++)
 {
   toRet+=x;
   toRet+=clock();
   toRet+=(unsigned long)str[x];
   if(toRet>max_rand)toRet&=(rand()%((max_rand+1) - min_rand) + min_rand);
 }

 if(toRet<min_rand)toRet=min_rand;
 return toRet;
}


Re: Random File and URL Opener

Posted: Tue Apr 05, 2016 10:32 am
by Octocontrabass
~ wrote:a simple "automagic" L that I don't know what really does anyway
It's in the C standard. Read the section on string literals. (Or type "c string l prefix" into Google.)

And while we're talking about strings, you're declaring wide strings as the wrong type. You should learn what the differences are between char, wchar_t, char16_t, and char32_t.
~ wrote:Also I added the following randomizing function which seems to improve randomness a lot over the standard rand() which seemed to always follow the same basic sequence of chosen files.
You could have saved yourself a lot of trouble by using srand().

Re: Random File and URL Opener

Posted: Tue Apr 05, 2016 11:19 am
by ~
I need an example to convert "D:\\[追寻记忆的痕迹].In.Search.of.Memory.2007.CHS.Scan-UNKNOWN.pdf" assuming UTF-8, to UTF-16, and vice-versa, using only L or cross-platform standard macros. But how to handle all encodings with a massive amount of random strings at runtime (ASCII, UTF-8, UTF-16, ANSI...)? Probably it would require using functions anyway, so I'm just preparing for it.

I think about detecting the text encoding for the whole webpage in Notepad++ or in Firefox/Chrome only using macros...

Octocontrabass wrote:
~ wrote:a simple "automagic" L that I don't know what really does anyway
It's in the C standard. Read the section on string literals. (Or type "c string l prefix" into Google.)

And while we're talking about strings, you're declaring wide strings as the wrong type. You should learn what the differences are between char, wchar_t, char16_t, and char32_t.
None of those types would map UTF-8 code points by themselves so I would have solved nothing without knowing how. Remember that I'm dealing with UTF-8 Unicode code point ranges with variable sizes per character (from 1 to 4 bytes) so the conversion is not straightforward. I wanted to implement a conversion function but I need to get used to the UTF-8 string format before understanding how.

StackOverflow: How many bytes does one Unicode character take?


As I said, it probably was better to convert them on the fly from UTF-8 to UTF-16.

Remember that I need to keep, generate and use strings in the exact format the WinAPI and the FAT/NTFS file systems store them, so I used the functions (WinAPI) that directly give me the functionality to convert from UTF-8 to the encoding that Windows uses (supposedly 16-bit Unicode).

Look at how nobody seems to talk about using the L for UTF-8 to UTF-16 conversion or vice-versa. And I tried many alternetives with no success before just using the WinAPI to convert the strings (from using the raw binary, the ASCII equivalent, to trying to convert to wide chars).

Google: utf-8 to utf-16 in c
StackOverflow: How do I convert UTF-8 to/from UTF-16 in C

Octocontrabass wrote:
~ wrote:
~ wrote:Also I added the following randomizing function which seems to improve randomness a lot over the standard rand() which seemed to always follow the same basic sequence of chosen files.
You could have saved yourself a lot of trouble by using srand().
We are OS developers. Far from being a trouble, it's an addition to the existing set of useful public domain snippets. I could add srand() to my randomizing function instead of only using it to try to make it more unpredictable.

Re: Random File and URL Opener

Posted: Tue Apr 05, 2016 12:52 pm
by kzinti
~ wrote:instead of a simple "automagic" L that I don't know what really does anyway
I suggest you start your recorder, than type "L" slowly in front of a string literal. Play it back over and over until you finally understand it. Isn't that what your recorder is for?

Re: Random File and URL Opener

Posted: Fri Apr 08, 2016 9:54 am
by max
Holy ****.. this dude.. maybe this is all just a massive communication issue