<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: DCL Script - Symbol Printing Previous Records Dates in Operating System - OpenVMS</title>
    <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851057#M37604</link>
    <description>&lt;P&gt;The logic in that code is incorrectly ordered; the write statements just don't happen at the appropriate part of processing each entry in SYSUAF. &amp;nbsp;As others have mentioned, debug the code.&amp;nbsp;&lt;/P&gt;&lt;P&gt;SYSUAF isn't always in SYS$SYSTEM. &amp;nbsp; Often times, it's not in that directory.&lt;/P&gt;&lt;P&gt;Protect those output files, as they contain sensitive data.&lt;/P&gt;&lt;P&gt;Consider writing scratch files to SYS$SCRATCH.&lt;/P&gt;&lt;P&gt;If you turn off procedure verification, be polite and reset it to the original value on exit.&lt;/P&gt;&lt;P&gt;Avoid editing the procedure to enable verification while debugging by using a procedure-specific logical name, as shown below.&lt;/P&gt;&lt;P&gt;Parsing the output of OpenVMS tools and utilities is not supported, subject to change and quite possibly&amp;nbsp;unreliable.&lt;/P&gt;&lt;P&gt;Preemptively close all channels before opening them (CLOSE/NOLOG), as interrupting a DCL loop due to an error or a ^Y can have some surprising (but expected) behavior.&lt;/P&gt;&lt;P&gt;I'd likely use the &lt;A href="http://labs.hoffmanlabs.com/node/1205" target="_blank"&gt;GETUAI&lt;/A&gt; tool here.&lt;/P&gt;&lt;P&gt;Here's what I think was intended, but I'm not entirely certain...&lt;/P&gt;&lt;PRE&gt;$ set noon
$ vfy = f$verify(f$trnlnm("DEBUG_GETREC"))
$!
$ if f$trnlnm("SYSUAF") .eqs. "" then DEFINE/USER SYSUAF SYS$SYSTEM:SYSUAF.DAT
$ uaf := "$authorize"
$ uaf list * /full
$
$ close/nolog infile
$ open/read infile sysuaf.lis
$ pwdl = ""
$!
$GETREC:
$ read/end=done infile rec
$
$! are we at a new entry?  If so, dump the previous entry
$ if f$length(f$edit(rec,"COLLAPSE")) .eq. 0
$ then
$   IF pwdl .EQS. "(none)" then call writerec
$   pwdl = ""
$   goto GETREC
$ endif
$
$! fetch the username data
$ IF f$Locate("Username:",rec) .NE. f$Length(rec)
$ then
$   foo = f$edit(f$element(1,":",rec),"TRIM,COMPRESS")
$   usr = f$edit(f$element(0," ",foo),"TRIM")
$   goto GETREC
$ endif
$
$! the pwdlifetime data, of course
$ IF f$Locate("Pwdlifetime:",rec) .EQ. 0
$ then
$   foo = rec - "Pwdlifetime:"
$   foooffset = f$locate("Pwdchange",foo)
$   foo = f$extract(0,foooffset,foo)
$   pwdl = f$edit(foo,"COLLAPSE")
$   goto GETREC
$ endif
$
$! you guessed it, the last login data
$ if f$locate("Last Login:",rec) .EQ. 0
$ then
$   foo = rec - "Last Login:" - "(interactive)" - "(non-interactive)"
$   foo = f$edit(foo,"COMPRESS,TRIM")
$   lastintlogin = f$edit(f$element(0,",",foo),"TRIM")
$   lastnonintlogin = f$edit(f$element(1,",",foo),"TRIM")
$   goto GETREC
$ endif
$
$ goto GETREC
$
$WRITEREC: subroutine
$ write sys$output "matching record: &amp;lt;''usr'&amp;gt; pwdl:&amp;lt;''pwdl'&amp;gt; int:&amp;lt;''lastintlogin'&amp;gt; nonint:&amp;lt;''lastnonintlogin'&amp;gt;"
$ endsubroutine
$
$DONE:
$! dump the last record, if we have one
$ IF pwdl .EQS. "(none)" then call writerec
$
$ close/nolog infile
$ vfy = f$verify(vfy)
$ exit&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 15 Apr 2016 18:13:38 GMT</pubDate>
    <dc:creator>Hoff</dc:creator>
    <dc:date>2016-04-15T18:13:38Z</dc:date>
    <item>
      <title>DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851009#M37599</link>
      <description>&lt;P&gt;Good Morning Everyone,&lt;/P&gt;&lt;P&gt;I am putting together a VMS DCL script that creates a sysuaf.lis file then searches this file for specific information. Currently I am searching for Username, Password Lifetime and the users last Interactive / Non-Interactive login dates. I take this information and print it all to a TXT file.&lt;/P&gt;&lt;P&gt;When the information is being printed to the file the Username and Pwdlifetime fields are correct. However, the dates are wrong. The dates that are being printed are from the previous users record and not the current record being printed. It is as if the date1 and date2 symbols are not gathering the current users data but instead holding onto the previous users record data.&amp;nbsp;&lt;/P&gt;&lt;P&gt;I will be wanting to search for users with the DisUser flag as well.&lt;/P&gt;&lt;P&gt;Below is a copy of my script.&lt;/P&gt;&lt;P&gt;Thanks in advance.&lt;/P&gt;&lt;PRE&gt;$ set noverify
$ set noon
$!
$ set def sys$system
$ uaf := "$authorize"
$ uaf list * /full
$
$ set def DSA1:[REPORTS]
$ open/read infile sys$system:sysuaf.lis
$ open/write outfile DSA1:[REPORTS]u_with_nexp_pwd.txt
$!
$ GETREC:
$ read/end = quit infile rec
$
$ npwd = ""
$
$! CHECK FOR A USERNAME !
$ IF f$Locate("Username:",rec) .NE. f$Length(rec)
$ then usr = f$extract(10,12,rec)
$ endif
$
$! CHECK FOR LAST INTERACTIVE &amp;amp; NON-INTERACTIVE DATES !
$ IF (f$Locate("Last Login:",rec) .EQ. 0) .AND. (f$Locate(":",rec) .NE. 0)
$ then
$ date1 = f$extr(12,11,rec)
$ date2 = f$extr(45,11,rec)
$ endif
$
$! CHECK FOR &amp;amp; EXTRACT VALUE IN PWDLIFETIME: FIELD !
$ IF f$Locate("Pwdlifetime:",rec) .NE. f$Length(rec)
$ then npwd = f$extract(23,6,rec)
$ endif
$ IF npwd .EQS. "(none)" then goto writerec
$
$ goto getrec
$
$ WRITEREC:
$ SHOW SYMBOL date1
$ wrtrec = usr+" "+npwd+" "+date1+" - "+date2
$ write outfile wrtrec
$ goto getrec
$
$ QUIT:
$ close infile
$ close outfile
$ exit
[End of file]&lt;/PRE&gt;</description>
      <pubDate>Fri, 15 Apr 2016 15:27:36 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851009#M37599</guid>
      <dc:creator>Bushytea</dc:creator>
      <dc:date>2016-04-15T15:27:36Z</dc:date>
    </item>
    <item>
      <title>Re: DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851028#M37600</link>
      <description>&lt;P&gt;&amp;gt; [...] It is as if the date1 and date2 symbols are not gathering the&lt;BR /&gt;&amp;gt; current users data but instead holding onto the previous users record&lt;BR /&gt;&amp;gt; data.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; Not a surprise.&amp;nbsp; In my listing, "Pwdlifetime:" appears before "Last&lt;BR /&gt;Login:", so, if you "goto writerec" after you find the "Pwdlifetime:",&lt;BR /&gt;then you will not yet have read the (next) "Last Login:" and its&lt;BR /&gt;corresponding dates.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HELP SET VERIFY&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; Generally, I'd figure that I was done reading a user's info when I&lt;BR /&gt;saw the next "Username:" (or end-of-file).&lt;BR /&gt;&lt;BR /&gt;&amp;gt; $ IF (f$Locate("Last Login:",rec) .EQ. 0) .AND. (f$Locate(":",rec) .NE. 0)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; What does the second F$LOCATE() do here?&lt;/P&gt;</description>
      <pubDate>Fri, 15 Apr 2016 16:52:44 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851028#M37600</guid>
      <dc:creator>Steven Schweda</dc:creator>
      <dc:date>2016-04-15T16:52:44Z</dc:date>
    </item>
    <item>
      <title>Re: DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851032#M37601</link>
      <description>&lt;P&gt;That line does two things. The first locate checks if that specified string Last Login: is found. The second locate protects against empty lines. Below is another way I have coded that line but I get the same results.&lt;/P&gt;&lt;PRE&gt;$! CHECK FOR LOGIN DATE !
$ IF f$Locate("Last Login:",rec) .NE. f$Length(rec)
$       then date1 = f$extr(12,11,rec)
$       date2 = f$extr(45,11,rec)
$ endif
$&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;I was thinking the same thing that based on the sysuaf file the pwdlifetime field is before the users login dates. I guess I was thinking incorrectly about the code and how it runs. I was thinking the code would run through collecting data until it reached the goto.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks,&lt;BR /&gt;Mike&lt;/P&gt;</description>
      <pubDate>Fri, 15 Apr 2016 17:03:31 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851032#M37601</guid>
      <dc:creator>Bushytea</dc:creator>
      <dc:date>2016-04-15T17:03:31Z</dc:date>
    </item>
    <item>
      <title>Re: DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851036#M37602</link>
      <description>&lt;P&gt;&amp;nbsp;&amp;nbsp; Do you really want to accumulate SYSUAF.LIS files in SYS$SYSTEM?&amp;nbsp; If&lt;BR /&gt;I were planning to run this more than once, then I'd put a little effort&lt;BR /&gt;into putting the AUTHORIZE output somewhere less SYSTEM-like.&amp;nbsp; AUTHORIZE&lt;BR /&gt;may be too lame to give you a choice beyond "placed in the current&lt;BR /&gt;default directory", but you can do something with that.&amp;nbsp; For example&lt;BR /&gt;(assuming that SYSUAF is not already defined, and F$TRNLNM() could tell&lt;BR /&gt;you that):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set default my_temp_dir&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; define /user_mode sysuaf sys$system:sysuaf.dat&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mcr authorize list * /full&lt;/P&gt;</description>
      <pubDate>Fri, 15 Apr 2016 17:10:17 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851036#M37602</guid>
      <dc:creator>Steven Schweda</dc:creator>
      <dc:date>2016-04-15T17:10:17Z</dc:date>
    </item>
    <item>
      <title>Re: DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851041#M37603</link>
      <description>&lt;P&gt;&amp;gt; [...] I was thinking the code would run through collecting data until&lt;BR /&gt;&amp;gt; it reached the goto.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; Nah.&amp;nbsp; DCL does pretty much what you tell it to do, not what you wish&lt;BR /&gt;it would do (when those differ).&lt;/P&gt;</description>
      <pubDate>Fri, 15 Apr 2016 17:14:41 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851041#M37603</guid>
      <dc:creator>Steven Schweda</dc:creator>
      <dc:date>2016-04-15T17:14:41Z</dc:date>
    </item>
    <item>
      <title>Re: DCL Script - Symbol Printing Previous Records Dates</title>
      <link>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851057#M37604</link>
      <description>&lt;P&gt;The logic in that code is incorrectly ordered; the write statements just don't happen at the appropriate part of processing each entry in SYSUAF. &amp;nbsp;As others have mentioned, debug the code.&amp;nbsp;&lt;/P&gt;&lt;P&gt;SYSUAF isn't always in SYS$SYSTEM. &amp;nbsp; Often times, it's not in that directory.&lt;/P&gt;&lt;P&gt;Protect those output files, as they contain sensitive data.&lt;/P&gt;&lt;P&gt;Consider writing scratch files to SYS$SCRATCH.&lt;/P&gt;&lt;P&gt;If you turn off procedure verification, be polite and reset it to the original value on exit.&lt;/P&gt;&lt;P&gt;Avoid editing the procedure to enable verification while debugging by using a procedure-specific logical name, as shown below.&lt;/P&gt;&lt;P&gt;Parsing the output of OpenVMS tools and utilities is not supported, subject to change and quite possibly&amp;nbsp;unreliable.&lt;/P&gt;&lt;P&gt;Preemptively close all channels before opening them (CLOSE/NOLOG), as interrupting a DCL loop due to an error or a ^Y can have some surprising (but expected) behavior.&lt;/P&gt;&lt;P&gt;I'd likely use the &lt;A href="http://labs.hoffmanlabs.com/node/1205" target="_blank"&gt;GETUAI&lt;/A&gt; tool here.&lt;/P&gt;&lt;P&gt;Here's what I think was intended, but I'm not entirely certain...&lt;/P&gt;&lt;PRE&gt;$ set noon
$ vfy = f$verify(f$trnlnm("DEBUG_GETREC"))
$!
$ if f$trnlnm("SYSUAF") .eqs. "" then DEFINE/USER SYSUAF SYS$SYSTEM:SYSUAF.DAT
$ uaf := "$authorize"
$ uaf list * /full
$
$ close/nolog infile
$ open/read infile sysuaf.lis
$ pwdl = ""
$!
$GETREC:
$ read/end=done infile rec
$
$! are we at a new entry?  If so, dump the previous entry
$ if f$length(f$edit(rec,"COLLAPSE")) .eq. 0
$ then
$   IF pwdl .EQS. "(none)" then call writerec
$   pwdl = ""
$   goto GETREC
$ endif
$
$! fetch the username data
$ IF f$Locate("Username:",rec) .NE. f$Length(rec)
$ then
$   foo = f$edit(f$element(1,":",rec),"TRIM,COMPRESS")
$   usr = f$edit(f$element(0," ",foo),"TRIM")
$   goto GETREC
$ endif
$
$! the pwdlifetime data, of course
$ IF f$Locate("Pwdlifetime:",rec) .EQ. 0
$ then
$   foo = rec - "Pwdlifetime:"
$   foooffset = f$locate("Pwdchange",foo)
$   foo = f$extract(0,foooffset,foo)
$   pwdl = f$edit(foo,"COLLAPSE")
$   goto GETREC
$ endif
$
$! you guessed it, the last login data
$ if f$locate("Last Login:",rec) .EQ. 0
$ then
$   foo = rec - "Last Login:" - "(interactive)" - "(non-interactive)"
$   foo = f$edit(foo,"COMPRESS,TRIM")
$   lastintlogin = f$edit(f$element(0,",",foo),"TRIM")
$   lastnonintlogin = f$edit(f$element(1,",",foo),"TRIM")
$   goto GETREC
$ endif
$
$ goto GETREC
$
$WRITEREC: subroutine
$ write sys$output "matching record: &amp;lt;''usr'&amp;gt; pwdl:&amp;lt;''pwdl'&amp;gt; int:&amp;lt;''lastintlogin'&amp;gt; nonint:&amp;lt;''lastnonintlogin'&amp;gt;"
$ endsubroutine
$
$DONE:
$! dump the last record, if we have one
$ IF pwdl .EQS. "(none)" then call writerec
$
$ close/nolog infile
$ vfy = f$verify(vfy)
$ exit&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 15 Apr 2016 18:13:38 GMT</pubDate>
      <guid>https://community.hpe.com/t5/operating-system-openvms/dcl-script-symbol-printing-previous-records-dates/m-p/6851057#M37604</guid>
      <dc:creator>Hoff</dc:creator>
      <dc:date>2016-04-15T18:13:38Z</dc:date>
    </item>
  </channel>
</rss>

