Link to home
Start Free TrialLog in
Avatar of Danny Kon
Danny KonFlag for Netherlands

asked on

Difficult question about subdirectories

As saying in the title this will be difficult maybe its not possible

What i am trying to do
I am trying to make a program what will use the command "calcs" to see automaticly what is the rights on a specific folder
say i have to have the "calcs" from SAP this will be on all different maps so what i do i make a log from the installation
and do a find on the main folders and i will show the rights of this main folder
The problom are the subfolders c:\program files\SAP\myprogram\ (are something like this)

But under the c:\program files\SAP\myprogram there is a sub folder and i want that the batch checks if this folder has the same rights and if it doesnt it will show the rights of this sub folder
This will be offcourse all the time different programs and the subfolders can be very deep

I am doing now something like this

FOR /F "TOKENS=*" %%i IN (SOMEFILE.TXT) DO SET PROGRA="%%i"
CALCS %PROGRA% >> OTHERFILE.TXT

So again this program can not show the rights from all subfolders otherwise it will be one big mess
It have to check if it has other rights and only if it has it will show


Using Windows xp


Dan
 
Avatar of DrWarezz
DrWarezz

Firstly, you keep using the command "CALCS", don't you mean: "CACLS" ?
I'm guessing so ...

So, you want to check all the subfolder rights of a specified directory, if any of them are different to the original directory, then it outputs that sub directories access rights, to a file?
Have a look at this:

::---------------------------------------- FileName.bat ------------------------------------------::
@echo off
for /f "tokens=*" %%i in (somefile.txt) do call :PROCESS %%i
goto :EOF

:PROCESS
for /d /r %%d in (%1) do CACLS %%d >>otherfile.txt
exit /b
::---------------------------------------- FileName.bat ------------------------------------------::

However, we still need to conclude a method to automate the batch file, to find out the access rights of each directory, and ONLY if they're different to the starting directory, do we output them.
That's mostly easy, the only thing I'm not too sure about, is HOW to find out the access rights of a directory. :o\

I'll have a look, and get back to you! :)

HTH :)
[r.D]
Okay;
when you type "CACLS aDirectory" at Command Prompt, it outputs something like this:

C:\aDirectory BUILTIN\Users:R
                    BUILTIN\Users:(OI)(CI)(IO)(special access:)

                                            GENERIC_READ
                                            GENERIC_EXECUTE
 
                    BUILTIN\Administrators:F
                    BUILTIN\Administrators:(OI)(CI)(IO)F
                    NT AUTHORITY\SYSTEM:F
                    NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F
                    CREATOR OWNER:(OI)(CI)(IO)F

Do you want to find out the access rights for the "BUILTIN\Users" ?  If so, then in the above example, the access rights would be "R" (Read).

Let me know, and I'll give you some code ;)

[r.D]
OR, do you simply want to compare the output, ie; in files, and if they're different at all, then it outputs it. If so, then something like this should do it (note, I haven't tested it):

::---------------------------------------- FileName.bat ------------------------------------------::
@echo off

set /p inputF="Input File: "
set /p outputF="Output File: "

if [%intputF%]==[] (
   echo Must specify an Input File.
   exit /b
)
if [%outputF%]==[] (
   echo Must specify an Output File.
   exit /b
)

for /f "tokens=*" %%d in (%inputF%) do (
   cacls %%d > temp.d
   call :PROCESS %%d
)

echo Complete.
goto :EOF

:PROCESS
for /d /r %%s in (%1) do (
   cacls %%s > temp.s
   echo n| comp temp.s temp.d >>NUL
   set err=%errorlevel%
   call :VERIFY %%s %err%
)
exit /b

:VERIFY
if %2 NEQ 0 cacls %1 >> %outputF%
exit /b

:EOF

::---------------------------------------- FileName.bat ------------------------------------------::

Like I say, I haven't tested it, but the logic makes sense! ;)

HTH :)
[r.D]
Avatar of Danny Kon

ASKER

DrWarezz,

This is only one of my problems,
So the meaning is that the file has to check IF there are any subdirectories and if there are subdirectories
than it has to output the cacls <--(you are right) of the main directory and if there are differentces between the main directory and the sub directory it also has to output the cacls of the sub directory and this has to go to every subdirectory on every level of this main directory
Any other info just ask.
BTW i dont know if to just do a compare on the output will do the trick because cacls will give an answer like this

Mainfolder:
C:\SAP BUILTIN\Users:R
                    BUILTIN\Users:(OI)(CI)(IO)(special access:)

                                            GENERIC_READ
                                            GENERIC_EXECUTE
 
                    BUILTIN\Administrators:F
                    BUILTIN\Administrators:(OI)(CI)(IO)F
                    NT AUTHORITY\SYSTEM:F
                    NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F
                    CREATOR OWNER:(OI)(CI)(IO)F
subfolder
C:\subfolderSAP BUILTIN\Users:R
                    BUILTIN\Users:(OI)(CI)(IO)(special access:)

                                            GENERIC_READ
                                            GENERIC_EXECUTE
 
                    BUILTIN\Administrators:F
                    BUILTIN\Administrators:(OI)(CI)(IO)F
                    NT AUTHORITY\SYSTEM:F
                    NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F
                    CREATOR OWNER:(OI)(CI)(IO)F

So this will never give an ok because it will give the name of the folder it displays
Dan
Also there is no need for an input as stated above i allready have the main folder in a variable and this variable is allready giving output to a txt file.

Dan
Okay..

>"So this will never give an ok because it will give the name of the folder it displays"
Ah yeah, woops. There's a way round that though. We'll come to that in a little while, for now though...

>"the file has to check IF there are any subdirectories"
Okay, to find out whether there exists any sub directories, this should do it:

: {
for %%c in ('dir /A:D /B') do if "%%c"=="" set subDirs=no
if "%subDirs%"=="no" (
   :// There are no subdirectories.
   exit
)
:// If the code gets to here, then sub directories exist ...
: }

I'll try and come up with some other code to compare the temp files, so that the Directory name is cancelled out.

HTH
[r.D]
So, to find out the access rights of a directory, you want to extract the character after the Directory? For example:

C:\subfolderSAP BUILTIN\Users:R

You'd want to extract the 'R', right?
No it just has to output the whole cacls and i also need to know the rights from all the users, admin etc etc just all the rights

Dan
Okay, this code should output the cacls to the file "temp.s" without the first line.

: {
      cacls %directoy% > temp1.s
      echo. > temp.s
      for /f "tokens=* skip=1 delims=" %%L in (temp1.s) do echo %%L >>temp.s
: }

Is that any good?
Let me know..

[r.D]
Or, simpler yet, this should work:
: {
      echo. > temp.s
      for /f "tokens=* skip=1 delims=" %%L in ('cacls %directory%') do echo %%L >>temp.s
: }
Okay, I've created a program, as below.
Basically, you place it in the directory that you want to process, and for every subdirectory in it, it will compare all of their Access Rights to the 'Super Directory's. If they're different, it outputs their Access Rights to a Results File (in this case: Results.txt):

://--------- 8<----------------------- FileName.bat -----------------------------------------\\:

:// Author: Rob Darkins
:// #This file outputs the access rights of every subdirectory,
://  if different to the super-dir.
://
:// (AR = Access Rights)

@echo off
TITLE SubDir Access Rights

:// Declare Variables:
: {
      set ResultsFile=Results.txt
      set TempSubFile=temp.s
      set TempDirFile=temp.d
      set TempSpaceFile=temp.t
: }
:// If the code gets to here, then sub directories exist ...
: }
:// Main Program:
: {
      echo.
      echo Processing Super Dir: %CD%
      
      :// Create the results file:
      : {
            echo These Directories do not have the same AR as their SuperDirectory: > %ResultsFile%
            echo  %CD% >>%ResultsFile%
            echo. >>%ResultsFile%
            echo ------------------------------------------------------------------ >>%ResultsFile%
      : }
      
      :// Output the AR of the SuperDirectory:
      : {
           echo. > %TempDirFile%
           for /f "tokens=* skip=1 delims=" %%L in ('cacls %CD%') do echo %%L >>%TempDirFile%
           call :RemoveSpaces %TempDirFile%
      : }
      
      :// For every subdirectory, compare it's AR to the SuperDir.
      :// If different, output it's AR to a file.
      : {
            for /d /r %%S in (*) do call :ProcessSub %%S
      : }
      
      :// Goto End Of File:
      goto :EOF
      
      :// The below work like functions, called in the above code:
      : {
            :// This 'function' processes a passed directory:
            :ProcessSub
                  : {
                        echo. > %TempSubFile%
                       for /f "tokens=* skip=1 delims=" %%L in ('cacls %1') do echo %%L >>%TempSubFile%
                       call :RemoveSpaces %TempSubFile%
                       echo n| comp %TempSubFile% %TempDirFile% >>NUL
                       if %errorlevel% neq 0 (
                             cacls %1 >>%ResultsFile%
                       )
                        exit /b
                  : }
            :// This 'function' removes all spaces within a file:
            :RemoveSpaces
            : {
                  echo. > %TempSpaceFile%
                  for /f "tokens=* skip=1 delims= " %%R in (%1) do @echo %%R >>%TempSpaceFile%
                  del %1 >>NUL
                  ren %TempSpaceFile% %1 >>NUL
                  exit /b
            : }
            :// This 'function' ends the process, and clears it up:
            :EOF
            : {
                  ping -n 2 localhost >>NUL
                  del %TempSubFile% >>NUL
                  del %TempDirFile% >>NUL
            : }
      : }
: }
://--------- 8<----------------------- FileName.bat -----------------------------------------\\:

I've test it, and it works fine for me. :)

best of luck,
[r.D]
However, at the moment; for EVERY Sub-Directory, it outputs:
 "Compare another file (Y/N) ?"  (Or something like that).

Just ignore that. If it REALLY bothers you however, then I can probably figure out how to prevent it.

:)
Here, I've also added the code (which I haven't tested mind you), that should exit if there doesn't exist any subdirectories.
here's the full wad:

://--------- 8<----------------------- FileName.bat -----------------------------------------\\:

:// Author: Rob Darkins
:// #This file outputs the access rights of every subdirectory,
://  if different to the super-dir.
://
:// (AR = Access Rights)

@echo off
TITLE SubDir Access Rights

:// Declare Variables:
: {
      set ResultsFile=Results.txt
      set TempSubFile=temp.s
      set TempDirFile=temp.d
      set TempSpaceFile=temp.t
: }
:// Verify that Sub-directories exist:
: {
      for /f "tokens=*" %%c in ('dir /A:D /B') do if "%%c"=="" (
            echo.
            echo No Sub-directories can be found.
            ping -n 2 localhost >>NUL
            exit
      )
: }
:// If the code gets to here, then sub directories exist ...
: }
:// Main Program:
: {
      echo.
      echo Processing Super Dir: %CD%
      
      :// Create the results file:
      : {
            echo These Directories do not have the same AR as their SuperDirectory: > %ResultsFile%
            echo  %CD% >>%ResultsFile%
            echo. >>%ResultsFile%
            echo ------------------------------------------------------------------ >>%ResultsFile%
      : }
      
      :// Output the AR of the SuperDirectory:
      : {
           echo. > %TempDirFile%
           for /f "tokens=* skip=1 delims=" %%L in ('cacls %CD%') do echo %%L >>%TempDirFile%
           call :RemoveSpaces %TempDirFile%
      : }
      
      :// For every subdirectory, compare it's AR to the SuperDir.
      :// If different, output it's AR to a file.
      : {
            for /d /r %%S in (*) do call :ProcessSub %%S
      : }
      
      :// Goto End Of File:
      goto :EOF
      
      :// The below work like functions, called in the above code:
      : {
            :// This 'function' processes a passed directory:
            :ProcessSub
                  : {
                        echo. > %TempSubFile%
                       for /f "tokens=* skip=1 delims=" %%L in ('cacls %1') do echo %%L >>%TempSubFile%
                       call :RemoveSpaces %TempSubFile%
                       echo n| comp %TempSubFile% %TempDirFile% >>NUL
                       if %errorlevel% neq 0 (
                             cacls %1 >>%ResultsFile%
                       )
                        exit /b
                  : }
            :// This 'function' removes all spaces within a file:
            :RemoveSpaces
            : {
                  echo. > %TempSpaceFile%
                  for /f "tokens=* skip=1 delims= " %%R in (%1) do @echo %%R >>%TempSpaceFile%
                  del %1 >>NUL
                  ren %TempSpaceFile% %1 >>NUL
                  exit /b
            : }
            :// This 'function' ends the process, and clears it up:
            :EOF
            : {
                  ping -n 2 localhost >>NUL
                  del %TempSubFile% >>NUL
                  del %TempDirFile% >>NUL
            : }
      : }
: }
://--------- 8<----------------------- FileName.bat -----------------------------------------\\:
ASKER CERTIFIED SOLUTION
Avatar of DrWarezz
DrWarezz

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Dr
firstly I am very impressed by your effort.
I am now at a place where is a different language windows installed and I tested the above file and doesnt seems to work
(normaly spoken the language will be standard US) I dont think so but maybe is this giving the problem
I went to a directory c:\program files\videolan, this file has one subdirectory and the program is giving all the time an output :

The system  can not find the file specified (translated from dutch)
Do you want to compare more files j/n

The results.txt gives this output

These Directories do not have the same AR as their SuperDirectory:
 C:\Program Files\VideoLAN

So something is not going good

Thanks in advance Dan
What OS are you on?
XP pro sp1 (Dutch version)
Hmm, same (but English version).
It MUST be because it's a Dutch version, that it's not working properly.. I cannot think of any other reason. :o\
For, it works fine on my machine.

It's normal for the program to give this output:
"Do you want to compare more files y/n"

For some reason, despite me using the 'echo n|' before the compare command (which successfuly bypasses the user having to type 'n' (or 'y') themselves), it still output "Do you want to compare more files y/n". The line of code that this occurs at is:

echo n| comp %TempSubFile% %TempDirFile% >>NUL

And despite me placing the ">>NUL" which should prevent all output, it continues to display the message.
But, if you can put up with it being there, then don't worry about. :)

Anyways, back to the main problem...

>"The system cannot find the file specified"
Could you remove the line (very near the beginning of the batch file) that says "@echo off" please?
THEN run the program. It will output LOADS of stuff, and will be a pain to read through, but I think it's our only chance. Basically, remove the "@echo off" and run the program like normal. Then, I want you to locate it, where the program outputs "The system cannot find the file specified", and have a look to see what the command is, BEFORE that is outputted.

I hope that makes sense.

:)
[r.D]
Drwarezz

Maybe it makes more sense to not go further testing this on a machine it will never be used on
Maybe for later to check where the problem is on the dutch version.
So tomorrow(monday) I will check the program on a US language and see how it will work.
Speak to you tomorrow.

Dan
Yeah - that would make more sense ;) hehe.
DrWarezz,

No this will not do the trick for me because the restriction of the rights
As stated in the start i have a variable what is the main directory.
My need is to use this variable to check for subdirs.

So it can not be done that the program have to be copied to the directory but it has to use the viariable

%progra% == main directory

Dan

 
Drwarezz,

I closed this question because you put so much effort in it but because of the reason that this didnt solve my problem
I grade the question B (is ex C)
I open a new question but in a little different contex because i didnt know it was possible to use the command cacls /t for showing
subdirs

I would appreciate it if you will go further with it

Q_21173505.html

Thanks for your time

Dan
Thanks alot Dan.
I'm sorry that I couldn't help much more.. I will have a read of the new question, and see if I can help more there :)

ThanQ
[r.D]