|
|
- /*
- * An example demonstrating wide-character functions
- *
- * Compile this file with Visual Studio and run the produced command in
- * console with a directory name argument. For example, command
- *
- * updatedb C:\
- *
- * will produce the file locate.db with one file name per line such as
- *
- * c:\Program Files/7-Zip/7-zip.chm
- * c:\Program Files/7-Zip/7-zip.dll
- * c:\Program Files/7-Zip/7z.dll
- * c:\Program Files/Adobe/Reader 10.0/Reader/logsession.dll
- * c:\Program Files/Adobe/Reader 10.0/Reader/LogTransport2.exe
- * c:\Program Files/Windows NT/Accessories/wordpad.exe
- * c:\Program Files/Windows NT/Accessories/write.wpc
- *
- * Be ware that this file uses wide-character API which is not compatible
- * with Linux or other major Unixes.
- *
- * Copyright (C) 1998-2019 Toni Ronkko
- * This file is part of dirent. Dirent may be freely distributed
- * under the MIT license. For all details and documentation, see
- * https://github.com/tronkko/dirent
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <wchar.h>
- #ifdef WIN32
- # include <io.h>
- # include <fcntl.h>
- #endif
- #include <dirent.h>
-
- /* File name and location of database file */
- #define DB_LOCATION L"locate.db"
-
-
- /* Forward-decl */
- static int update_directory (const wchar_t *dirname);
- static void db_open (void);
- static void db_close (void);
- static void db_store (const wchar_t *dirname);
-
-
- /* Module local variables */
- static FILE *db = NULL;
-
-
- int
- main(
- int argc, char *argv[])
- {
- #ifdef WIN32
- int i;
- int ok;
-
- /* Prepare for unicode output */
- _setmode (_fileno (stdout), _O_U16TEXT);
-
- /* Open locate.db */
- db_open ();
-
- /* For each directory in command line */
- i = 1;
- while (i < argc) {
- wchar_t buffer[PATH_MAX + 1];
- errno_t error;
- size_t n;
-
- /* Convert ith argument to wide-character string */
- error = mbstowcs_s (&n, buffer, PATH_MAX, argv[i], _TRUNCATE);
- if (!error) {
-
- /* Scan directory for files */
- ok = update_directory (buffer);
- if (!ok) {
- wprintf (L"Cannot open directory %s\n", buffer);
- exit (EXIT_FAILURE);
- }
-
- }
-
- i++;
- }
-
- /* Use current working directory if no arguments on command line */
- if (argc == 1) {
- update_directory (L".");
- }
-
- db_close ();
- #else
- printf ("updatedb only works on Microsoft Windows\n");
- #endif
-
- return EXIT_SUCCESS;
- }
-
- /* Find files recursively */
- static int
- update_directory(
- const wchar_t *dirname)
- {
- int ok = 0;
-
- #ifdef WIN32
- _WDIR *dir;
- wchar_t buffer[PATH_MAX + 2];
- wchar_t *p = buffer;
- const wchar_t *src;
- wchar_t *end = &buffer[PATH_MAX];
-
- /* Copy directory name to buffer */
- src = dirname;
- while (p < end && *src != '\0') {
- *p++ = *src++;
- }
- *p = '\0';
-
- /* Open directory stream */
- dir = _wopendir (dirname);
- if (dir != NULL) {
- struct _wdirent *ent;
-
- /* Print all files and directories within the directory */
- while ((ent = _wreaddir (dir)) != NULL) {
- wchar_t *q = p;
- wchar_t c;
-
- /* Get final character of directory name */
- if (buffer < q) {
- c = q[-1];
- } else {
- c = ':';
- }
-
- /* Append directory separator if not already there */
- if (c != ':' && c != '/' && c != '\\') {
- *q++ = '/';
- }
-
- /* Append file name */
- src = ent->d_name;
- while (q < end && *src != '\0') {
- *q++ = *src++;
- }
- *q = '\0';
-
- /* Decide what to do with the directory entry */
- switch (ent->d_type) {
- case DT_REG:
- /* Store file name */
- db_store (buffer);
- break;
-
- case DT_DIR:
- /* Scan sub-directory recursively */
- if (wcscmp (ent->d_name, L".") != 0
- && wcscmp (ent->d_name, L"..") != 0) {
- update_directory (buffer);
- }
- break;
-
- default:
- /* Do not device entries */
- /*NOP*/;
- }
-
- }
-
- wclosedir (dir);
- ok = 1;
-
- } else {
-
- /* Cannot open directory */
- ok = 0;
-
- }
- #endif
-
- return ok;
- }
-
- /* Store file name to locate.db */
- static void
- db_store(
- const wchar_t *dirname)
- {
- #ifdef WIN32
- if (db) {
- /* Output line to file */
- fwprintf (db, L"%s\n", dirname);
- } else {
- wprintf (L"Database not open\n");
- exit (EXIT_FAILURE);
- }
- #endif
- }
-
- /* Open database file locate.db */
- static void
- db_open(
- void)
- {
- #ifdef WIN32
- if (db == NULL) {
- errno_t error;
-
- /* Open file for writing */
- error = _wfopen_s (&db, DB_LOCATION, L"wt, ccs=UNICODE");
- if (error) {
- wprintf (L"Cannot open %s\n", DB_LOCATION);
- exit (EXIT_FAILURE);
- }
- }
- #endif
- }
-
- /* Close database file */
- static void
- db_close(
- void)
- {
- if (db) {
- fclose (db);
- db = NULL;
- }
- }
|