\documentclass[a4paper,12pt]{article}
\usepackage[procnames,noindent]{lgrind}
\usepackage{fancyhdr,geometry}
\geometry{top=15mm,bottom=12mm,left=20mm,right=5mm,headheight=14.5pt,
          marginparwidth=25mm}
\pagestyle{fancy}
\fancyhead[C]{}
\fancyhead[LO,RE]{\bfseries\lgrindfilename}
\fancyhead[RO,LE]{\bfseries\thepage}
\fancyfoot[C]{}
\begin{document}
\begin{lgrind}
\Head{}
\File{migrate\-users}{2002}{Feb}{18}{10:40}{46995}
\L{\LB{\C{}\#!_\1usr\1bin\1perl_-w}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Nick_Urbanik_\<nicku@vtc.edu.hk\>}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Migrate_student_ICT_account_information_from_ldap.vtc.edu.hk_and_}}
\CE{}\L{\LB{\C{}\#_produce_an_LDIF_file_suitable_for_slapadd\4ing_to_ictlab.tyict.vtc.edu.hk.}}
\CE{}\L{\LB{\C{}\#_Algorithm:}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_create_the_group_students_in_tyict_if_it_doesn\4t_exist_there}}
\CE{}\L{\LB{\C{}\#_Read_all_groups_from_tyict_into_a_hash_\%groups}}
\CE{}\L{\LB{\C{}\#_Read_all_uidNumbers,_gidNumbers_into_two_hashes}}
\CE{}\L{\LB{\C{}\#_for_each_student_in_ldap.vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#_____start_from_max\_uidNumber,_assign_uidNumber,_gidNumber_to_user.}}
\CE{}\L{\LB{\C{}\#_____if_course_is_not_in_\%groups}}
\CE{}\L{\LB{\C{}\#_________create_the_group_in_tyict_using_next_available_gidNumber}}
\CE{}\L{\LB{\C{}\#_________put_the_group_in_\%groups}}
\CE{}\L{\LB{\C{}\#_____if_\4year\4_._\$year_is_not_in_\%groups}}
\CE{}\L{\LB{\C{}\#_________create_the_group_in_tyict_using_next_available_gidNumber}}
\CE{}\L{\LB{\C{}\#_________put_the_group_in_\%groups}}
\CE{}\L{\LB{\C{}\#_____add_the_student_as_a_user_to_tyict}}
\CE{}\L{\LB{\C{}\#_____add_the_student_to_the_group_students}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#__\#_000000153,BA,ST,stu,vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#__dn:_uid=000000153,ou=BA,ou=ST,ou=stu,o=vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#__uid:_000000153}}
\CE{}\L{\LB{\C{}\#__cn:_TONG_Chung_Man}}
\CE{}\L{\LB{\C{}\#__academicyear:_2000}}
\CE{}\L{\LB{\C{}\#__year:_1}}
\CE{}\L{\LB{\C{}\#__course:_21310}}
\CE{}\L{\LB{\C{}\#__courseduration:_3}}
\CE{}\L{\LB{\C{}\#__registrationdate:_31-08-2000}}
\CE{}\L{\LB{\C{}\#__site:_ST}}
\CE{}\L{\LB{\C{}\#__department:_BA}}
\CE{}\L{\LB{\C{}\#__actype:_STU}}
\CE{}\L{\LB{\C{}\#__acowner:_000000153}}
\CE{}\L{\LB{\C{}\#__nsmsgdisallowaccess:_imap}}
\CE{}\L{\LB{\C{}\#__mailhost:_hqmail.vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#__mail:_000000153@stu.vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#__mailquota:_5242880}}
\CE{}\L{\LB{\C{}\#__maildeliveryoption:_mailbox}}
\CE{}\L{\LB{\C{}\#__nswmextendeduserprefs:_meDraftFolder=Drafts}}
\CE{}\L{\LB{\C{}\#__nswmextendeduserprefs:_meSentFolder=Sent}}
\CE{}\L{\LB{\C{}\#__nswmextendeduserprefs:_meTrashFolder=Trash}}
\CE{}\L{\LB{\C{}\#__nswmextendeduserprefs:_meInitialized=true}}
\CE{}\L{\LB{\C{}\#__classcode:_B}}
\CE{}\L{\LB{\C{}\#__objectclass:_top}}
\CE{}\L{\LB{\C{}\#__objectclass:_person}}
\CE{}\L{\LB{\C{}\#__objectclass:_student}}
\CE{}\L{\LB{\C{}\#__objectclass:_organizationalPerson}}
\CE{}\L{\LB{\C{}\#__objectclass:_inetOrgPerson}}
\CE{}\L{\LB{\C{}\#__objectclass:_mailrecipient}}
\CE{}\L{\LB{\C{}\#__objectclass:_nsmessagingserveruser}}
\CE{}\L{\LB{\C{}\#__objectclass:_VTC}}
\CE{}\L{\LB{\C{}\#__finalyear:_F}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#__dn:_uid=se4a15,ou=People,dc=tyict,dc=vtc,dc=edu,dc=hk}}
\CE{}\L{\LB{\C{}\#__uid:_se4a15}}
\CE{}\L{\LB{\C{}\#__cn:_se4a15}}
\CE{}\L{\LB{\C{}\#__sn:_se4a15}}
\CE{}\L{\LB{\C{}\#__mail:_se4a15@vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#__objectClass:_person}}
\CE{}\L{\LB{\C{}\#__objectClass:_organizationalPerson}}
\CE{}\L{\LB{\C{}\#__objectClass:_inetOrgPerson}}
\CE{}\L{\LB{\C{}\#__objectClass:_account}}
\CE{}\L{\LB{\C{}\#__objectClass:_posixAccount}}
\CE{}\L{\LB{\C{}\#__objectClass:_top}}
\CE{}\L{\LB{\C{}\#__objectClass:_kerberosSecurityObject}}
\CE{}\L{\LB{\C{}\#__userPassword:_\{crypt\}gGO6spPkzxB9I}}
\CE{}\L{\LB{\C{}\#__krbname:_se4a15@VTC.EDU.HK}}
\CE{}\L{\LB{\C{}\#__loginShell:_\1bin\1csh}}
\CE{}\L{\LB{\C{}\#__uidNumber:_3015}}
\CE{}\L{\LB{\C{}\#__gidNumber:_3015}}
\CE{}\L{\LB{\C{}\#__homeDirectory:_\1home\1se4a15}}
\CE{}\L{\LB{\C{}\#_Also_telephonenumber:_roomnumber:_homephone:_givenname:_sn:}}
\CE{}\L{\LB{\C{}\#_mail:_\$user\2@\$DEFAULT\_MAIL\_DOMAIN_mailHost:_\$DEFAULT\_MAIL\_HOST}}
\CE{}\L{\LB{\C{}\#_objectClass:_inetLocalMailRecipient}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#__dn:_cn=students,ou=Group,dc=tyict,dc=vtc,dc=edu,dc=hk}}
\CE{}\L{\LB{\C{}\#__objectClass:_posixGroup}}
\CE{}\L{\LB{\C{}\#__objectClass:_top}}
\CE{}\L{\LB{\C{}\#__cn:_students}}
\CE{}\L{\LB{\C{}\#__userPassword:_\{crypt\}x}}
\CE{}\L{\LB{\C{}\#__gidNumber:_528}}
\CE{}\L{\LB{\C{}\#__memberUid:_stu1}}
\CE{}\L{\LB{\C{}\#__memberUid:_stu2}}
\CE{}\L{\LB{\C{}\#__memberUid:_stu3}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#__dn:_cn=toby,ou=auto.home,dc=tyict,dc=vtc,dc=edu,dc=hk}}
\CE{}\L{\LB{\C{}\#__objectClass:_automount}}
\CE{}\L{\LB{\C{}\#__cn:_toby}}
\CE{}\L{\LB{\C{}\#__automountInformation:_-rw,hard,intr_alpha.tycm.vtc.edu.hk:\1usr\1users\1home\1staff\1toby}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#__dn:_cn=nicku,ou=auto.home,dc=tyict,dc=vtc,dc=edu,dc=hk}}
\CE{}\L{\LB{\C{}\#__objectClass:_automount}}
\CE{}\L{\LB{\C{}\#__cn:_nicku}}
\CE{}\L{\LB{\C{}\#__automountInformation:_-rw,hard,intr_ictlab.tyict.vtc.edu.hk:\1home\1nicku}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Password_generator_from_ark_A._Pors,_mark@dreamzpace.com,_www.dreamzpace.com}}
\CE{}\L{\LB{}}
\L{\LB{\V{use}_\V{strict};}}
\L{\LB{}}
\L{\LB{\V{use}_\V{Net}::\V{LDAP}_\V{qw}\1_:\V{all}_\1;}}
\L{\LB{\V{use}_\V{Net}::\V{LDAP}::\V{Util}_\V{qw}(_\V{ldap\_error\_name}}}
\L{\LB{_______________________\V{ldap\_error\_text}_);\C{}____\#_use_for_Error_handling}}
\CE{}\L{\LB{\V{use}_\V{DB\_File};}}
\L{\LB{\V{use}_\V{Getopt}::\V{Long};}}
\L{\LB{\V{use}_\V{File}::\V{Basename};}}
\L{\LB{\V{use}_\V{constant}_\V{GID\_MAX}_=\>_\N{60000};}}
\L{\LB{}}
\L{\LB{\K{die}_\S{}\3You_must_be_root_for_this_program_to_work_properly.\2n\3\SE{}_\K{unless}_\N{\$}\<_==_\N{0};}}
\L{\LB{}}
\L{\LB{\C{}\#_Turn_on_autoflushing_so_can_watch_output_with_tail:}}
\CE{}\L{\LB{\N{\$}\|=\N{1};}}
\L{\LB{}}
\L{\LB{\C{}\#_Avoid_clobbering_old_password_files.}}
\CE{}\L{\LB{\C{}\#_Probably_better_to_use_a_database.}}
\CE{}\L{\LB{\V{our}_\N{\$passwd}\V{\_info\_file}_=_\S{}\3\1root\1ldapaccounts\1password\-info\-file\-\3\SE{}}}
\L{\LB{____._\K{time}_._\S{}\3.txt\3\SE{};}}
\L{\LB{\V{our}_\N{\$passwd}\V{\_dbm\_database}_=_\S{}\3\1root\1ldapaccounts\1password\-database\3\SE{};}}
\L{\LB{\C{}\#_our_\$max\_uid\_group\_file_=_\3\1root\1ldapaccounts\1max-uid-group\_numbers.txt\3;}}
\CE{}\L{\LB{\V{our}_\%\V{passwd\_dbm\_hash};}}
\L{\LB{\V{our}_\N{\$base}_=_\S{}\3dc=tyict,dc=vtc,dc=edu,dc=hk\3\SE{};}}
\L{\LB{\V{our}_\N{\$automount}\V{\_options}_=_\S{}\3\-rw,hard,intr\3\SE{};}}
\L{\LB{\V{our}_\N{\$nfs}\V{\_server}_=_\S{}\3ictlab.tyict.vtc.edu.hk\3\SE{};}}
\L{\LB{\V{our}_\N{\$$\ell$dap}\V{\_server}_=_\S{}\3ldap.tyict.vtc.edu.hk\3\SE{};}}
\L{\LB{\V{our}_\N{\$kerberos}\V{\_realm}_=_\S{}\3TYICT.VTC.EDU.HK\3\SE{};}}
\L{\LB{\V{our}_\N{\$home}\V{\_dir\_base}_=_\S{}\3\1home\3\SE{};}}
\L{\LB{\V{our}_\N{\$debug}_=_\N{1};}}
\L{\LB{\C{}\#_True_if_you_want_to_generate_new_passwords_for_everybody:}}
\CE{}\L{\LB{\C{}\#_our_\$gen\_new\_password_=_0;}}
\CE{}\L{\LB{\V{our}_\N{\$useradd}_=_\N{0};}}
\L{\LB{\V{our}_\N{\$import}\V{\_vtc\_ldap}_=_\N{0};}}
\L{\LB{\V{our}_\N{\$orac$\ell$e}\V{\_part\_time\_text\_files}_=_\N{0};}}
\L{\LB{\V{our}_\N{\$grs}\V{\_part\_time\_text\_files}_=_\N{0};}}
\L{\LB{\V{our}_\N{\$uid}\V{\_to\_add};}}
\L{\LB{\V{our}_\N{\$users}\V{\_full\_name};}}
\L{\LB{\V{our}_\N{\$emai$\ell$}\V{\_address};}}
\L{\LB{\V{our}_@\V{other\_groups};}}
\L{\LB{\V{our}_\N{\$passwd};}}
\L{\LB{}}
\L{\LB{\V{use}_\V{constant}_\V{GROUP\_DEBUG}_=\>_\N{3};}}
\L{\LB{}}
\L{\LB{\K{open}_\V{OUTPUT},_\S{}\3\>\&STDOUT\3\SE{}_\V{or}_\K{die}_\S{}\3Cannot_dup_standard_output:_\$!\3\SE{};}}
\L{\LB{}}
\L{\LB{\V{our}_\N{\$$\ell$dap}\V{\_ict}_=_\V{Net}::\V{LDAP}\-\!\>\V{new}(_\N{\$$\ell$dap}\V{\_server}_)_\V{or}_\K{die}_\S{}\3\$@\3\SE{};}}
\L{\LB{\V{our}_\N{\$mesg}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\K{bind}(_\V{version}_=\>_\N{3}_);\C{}__\#_use_for_searches}}
\CE{}\L{\LB{}}
\L{\LB{\K{die}_\S{}\3Failed_to_bind:_\3\SE{},_\N{\$mesg}\-\!\>\V{code}(),_\S{}\3\2n\3\SE{}_\K{if}_\N{\$mesg}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{}}
\L{\LB{\V{our}_(_\%\V{group\_byname},_\%\V{group\_bynumber}_);}}
\L{\LB{\C{}\#_\%group\_byname_is_a_simple_hash_of_gidNumbers_indexed_by_gid.}}
\CE{}\L{\LB{\C{}\#_\%group\_bynumber_is_a_hash_with_key_=_gidNumber.}}
\CE{}\L{\LB{\C{}\#_Each_entry_is_a_reference_to_a_hash_of_two_entries,_one_the_gid,}}
\CE{}\L{\LB{\C{}\#_the_other_the_list_of_members.}}
\CE{}\L{\LB{\C{}\#_The_key_for_gid_is_\4gid\4.}}
\CE{}\L{\LB{\C{}\#_The_key_for_members_is_\4members\4.}}
\CE{}\L{\LB{}}
\L{\LB{}}
\L{\LB{\C{}\#_For_generating_the_passwords:}}
\CE{}\L{\LB{\V{our}_@\V{dict};}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{slurp\_entire\_dictionary}()}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$dict}_=_\S{}\4\1usr\1share\1dict\1words\4\SE{};\C{}_\#_path_to_dict_file}}
\CE{}\L{\LB{____\K{open}(_\V{DICT},_\S{}\3\<_\$dict\3\SE{}_)_\|\,\|_\K{die}_\S{}\3Cannot_open_dict:_\$!\3\SE{};}}
\L{\LB{____\K{while}_(_\<\V{DICT}\>_)}}
\L{\LB{____\{}}
\L{\LB{________\V{chomp};}}
\L{\LB{________\K{push}_@\V{dict},_\N{\$}\V{\_};}}
\L{\LB{____\}}}
\L{\LB{____\K{close}_\V{DICT};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_If_you_pass_some_string_as_a_parameter,_that_will_be_used_as_the_password.}}
\CE{}\L{\LB{\C{}\#_If_parameter_is_empty,_then_will_use_the_generated_password.}}
\CE{}\L{\LB{\K{sub}_\V{gen\_password}(\N{\$})}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$p$\ell$ain}\V{\_passwd}_=_\K{shift};}}
\L{\LB{____\V{my}_@\K{sub}_=_();}}
\L{\LB{____\V{my}_\N{\$word}_=_\S{}\4\4\SE{};}}
\L{\LB{____\V{my}_\N{\$word$\ell$en}_=_\N{8};\C{}____________________\#_desired_length_of_the_password}}
\CE{}\L{\LB{____\V{my}_\N{\$sub$\ell$en}_=_\N{3};\C{}____\#_length_of_the_word_chunks_that_create_the_password}}
\CE{}\L{\LB{____\V{my}_\N{\$parts}_=_\K{int}_(\N{\$word$\ell$en}\1\N{\$sub$\ell$en});}}
\L{\LB{____\V{my}_\N{\$numwords}_=_\N{100};\C{}_________________\#_number_of_passwords_to_print}}
\CE{}\L{\LB{}}
\L{\LB{\C{}____\#_The_outer_loop_should_very_seldom_execute_more_than_once,}}
\CE{}\L{\LB{\C{}____\#_but_sometimes_the_dictionary_contains_apostrophes,_which_once_stuffed_up}}
\CE{}\L{\LB{\C{}____\#_the_call_to_slappasswd_before_I_quoted_the_word.}}
\CE{}\L{\LB{\C{}\#____do}}
\CE{}\L{\LB{\C{}\#____\{}}
\CE{}\L{\LB{________\K{for}_(_\V{my}_\N{\$i}=\N{0};_\N{\$i}_\<_\N{\$parts};_\N{\$i}++)}}
\L{\LB{________\{}}
\L{\LB{____________\K{do}}}
\L{\LB{____________\{}}
\L{\LB{________________\N{\$sub}[\N{\$i}]_=_\K{substr}_(\N{\$dict}[\K{int}_(\K{rand}_@\V{dict})],_\N{0},_\N{\$sub$\ell$en});}}
\L{\LB{____________\}}}
\L{\LB{____________\K{until}_(\K{length}_\N{\$sub}[\N{\$i}]_==_\N{\$sub$\ell$en});}}
\L{\LB{____________\N{\$word}_.=_\N{\$sub}[\N{\$i}];}}
\L{\LB{________\}}}
\L{\LB{}}
\L{\LB{________\V{my}_\N{\$$\ell$eft}_=_\N{\$word$\ell$en}_\%_\N{\$sub$\ell$en};}}
\L{\LB{________\N{\$word}_.=_\K{substr}_(\K{int}_\K{rand}_(\N{10}\*\*(\N{\$word$\ell$en}_\-_\N{1})),_\N{0},_\N{\$$\ell$eft});}}
\L{\LB{\C{}\#____\}_while_\$word_=\~_m\1[\5a-zA-Z0-9\1;}}
\CE{}\L{\LB{____\N{\$word}_=_\N{\$p$\ell$ain}\V{\_passwd}_\K{if}_\N{\$p$\ell$ain}\V{\_passwd};}}
\L{\LB{____\V{my}_\N{\$md5}\V{\_hash}_=_{`}\V{slappasswd}_\-\V{h}_\S{}\3\{MD5\}\3\SE{}_\-\K{s}_\S{}\3\$word\3\SE{}{`};}}
\L{\LB{____\V{chomp}_\N{\$md5}\V{\_hash};}}
\L{\LB{____\K{return}_(_\N{\$word},_\N{\$md5}\V{\_hash}_);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_Avoid_trying_to_generate_GID_numbers_above_nfsnobody:}}
\CE{}\L{\LB{\Proc{max\_below\_GID\_MAX}\K{sub}_\V{max\_below\_GID\_MAX}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$max}_=_\K{shift}(@\V{\_});}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$foo}_(@\V{\_})_\{}}
\L{\LB{________\N{\$max}_=_\N{\$foo}_\K{if}_\N{\$max}_\<_\N{\$foo}_\V{and}_\N{\$foo}_\<_\V{GID\_MAX};}}
\L{\LB{____\}}}
\L{\LB{____\K{return}_\N{\$max};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\V{our}_\N{\$max}\V{\_uid\_number}_=_\N{0};}}
\L{\LB{\Proc{get\_next\_uid\_number}\K{sub}_\V{get\_next\_uid\_number}}}
\L{\LB{\{}}
\L{\LB{____\K{return}_++\N{\$max}\V{\_uid\_number}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{get\_user\_names}(\N{\$})}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$cn}_=_\K{shift};}}
\L{\LB{____\V{my}_@\V{names}_=_\K{split}_\1_+\1,_\N{\$cn};}}
\L{\LB{____\V{my}_(_\N{\$sn},_\N{\$givenName}_);}}
\L{\LB{____\K{if}_(_@\V{names}_==_\N{2}_)}}
\L{\LB{____\{}}
\L{\LB{________(_\N{\$givenName},_\N{\$sn}_)_=_@\V{names};}}
\L{\LB{________\N{\$givenName}_=_\V{ucfirst}_\V{lc}_\N{\$givenName};}}
\L{\LB{________\N{\$sn}_=_\V{ucfirst}_\V{lc}_\N{\$sn};}}
\L{\LB{________\N{\$cn}_=_\S{}\3\$givenName_\$sn\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_@\V{names}_==_\N{3}_)}}
\L{\LB{____\{}}
\L{\LB{________\N{\$sn}_=_\K{shift}_@\V{names};}}
\L{\LB{________\N{\$sn}_=_\V{ucfirst}_\V{lc}_\N{\$sn};}}
\L{\LB{________\N{\$givenName}_=_\V{ucfirst}_\V{lc}_\K{join}_\S{}\4\-\4\SE{},_@\V{names};}}
\L{\LB{________\N{\$cn}_=_\S{}\3\$sn_\$givenName\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_@\V{names}_\>_\N{3}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_Assume_that_the_last_name_is_a_western_name.}}
\CE{}\L{\LB{________\N{\$sn}_=_\K{shift}_@\V{names};}}
\L{\LB{________\N{\$sn}_=_\V{ucfirst}_\V{lc}_\N{\$sn};}}
\L{\LB{________\V{my}_\N{\$kwai$\ell$o}\V{\_name}_=_\V{ucfirst}_\V{lc}_\K{pop}_@\V{names};}}
\L{\LB{________\N{\$givenName}_=_(_\V{ucfirst}_\V{lc}_\K{join}_\S{}\4\-\4\SE{},_@\V{names}_)_._\S{}\3,_\$kwailo\_name\3\SE{};}}
\L{\LB{________\N{\$cn}_=_\S{}\3\$sn_\$givenName\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_@\V{names}_==_\N{1}_)}}
\L{\LB{____\{}}
\L{\LB{________\N{\$cn}_=_\N{\$sn}_=_\V{ucfirst}_\V{lc}_\K{shift}_@\V{names};}}
\L{\LB{________\N{\$givenName}_=_\S{}\3(unknown)\3\SE{};}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_\$cn_has_only_one_name_provided\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\N{\$cn}_=_\N{\$sn}_=_\N{\$givenName}_=_\S{}\3(unknown)\3\SE{};}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_no_name_provided\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{\C{}____\#_The_old_GRS_put_a_comma_between_family_and_given_names:}}
\CE{}\L{\LB{____\N{\$cn}_=\~_\K{s}\1,\1\1_\K{if}_\N{\$sn}_=\~_\K{s}\1,\1\1;}}
\L{\LB{____\K{return}_(_\N{\$cn},_\N{\$sn},_\N{\$givenName}_);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{get\_next\_gid\_number}\K{sub}_\V{get\_next\_gid\_number}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$max}_=_\V{max\_below\_GID\_MAX}_\K{sort}_\K{keys}_\%\V{group\_bynumber};}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Biggest_gidnumber_is_\$max\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____\K{return}_\N{\$max}_+_\N{1};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_This_is_really_for_adding_users_to_secondary_groups.}}
\CE{}\L{\LB{\C{}\#_Assume_have_already_bound_to_server_as_admin.}}
\CE{}\L{\LB{\Proc{add\_uid\_to\_group}\K{sub}_\V{add\_uid\_to\_group}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$uid},_\N{\$gid}_)_=_@\V{\_};}}
\L{\LB{____\K{print}_\S{}\3add\_uid\_to\_group(uid=\$uid,_gid=\$gid)\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____\K{if}_(_\N{\$uid}_\V{eq}_\N{\$gid}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\2n\2n\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\3\SE{};}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_add\_uid\_to\_group_should_be_used_for_adding_to_secondary_\3\SE{},}}
\L{\LB{____________\S{}\3groups,_not_primary_groups.__The_subroutine_is_called_in_\3\SE{},}}
\L{\LB{________________\S{}\3the_wrong_place.\2n\3\SE{};}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\2n\2n\3\SE{};}}
\L{\LB{________\K{return};\C{}_\#_probably_should_die.}}
\CE{}\L{\LB{____\}}}
\L{\LB{____\K{if}_(_\V{not}_\V{exists}_\N{\$group}\V{\_byname}\{\N{\$gid}\}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{create\_group}(_\N{\$gid},_\V{get\_next\_gid\_number}(),_(_\N{\$uid}_)_);}}
\L{\LB{________\K{return};}}
\L{\LB{____\}}}
\L{\LB{____\V{my}_\N{\$dn}_=_\S{}\3cn=\$gid,ou=Group,\$base\3\SE{};}}
\L{\LB{\C{}____\#_We_must_be_adding_the_user_to_an_existing_secondary_group:}}
\CE{}\L{\LB{\C{}____\#_Nick,_13_Sept_2001:}}
\CE{}\L{\LB{\C{}____\#_I_changed_this_from_add,_since_I_want_it_to_succeed_even_if_user_is_already}}
\CE{}\L{\LB{\C{}____\#_a_member.__See_if_it_works.}}
\CE{}\L{\LB{\C{}____\#_No,_it_results_in_each_group_having_only_one_member.}}
\CE{}\L{\LB{____\K{if}_(_\K{grep}_\1\N{\$uid}\1,_@\{_\N{\$group}\V{\_bynumber}\{\N{\$group}\V{\_byname}\{\N{\$gid}\}\}\{\S{}\4members\4\SE{}\}_\}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\$uid_is_already_a_member_of_group_\$gid.\2n\3\SE{};}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3members_of_\$gid:_\3\SE{},}}
\L{\LB{___________\K{join}(_\S{}\4,_\4\SE{},__@\{_\N{\$group}\V{\_bynumber}\{\N{\$group}\V{\_byname}\{\N{\$gid}\}\}\{\S{}\4members\4\SE{}\}_\}_),}}
\L{\LB{________________\S{}\3\2n\3\SE{}_\K{if}_\N{\$debug}_\>_\V{GROUP\_DEBUG};}}
\L{\LB{________\K{return};}}
\L{\LB{____\}}}
\L{\LB{____\V{my}_\N{\$resu$\ell$t}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{modify}(_\N{\$dn},_\V{add}_=\>_\{_\V{memberUid}_=\>_\N{\$uid}_\}_);}}
\L{\LB{____\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_failed_to_add_\$uid_to_\$dn:_\3\SE{},_\N{\$resu$\ell$t}\-\!\>\V{error};}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{push}_@\{_\N{\$group}\V{\_bynumber}\{\N{\$group}\V{\_byname}\{\N{\$gid}\}\}\{\S{}\4members\4\SE{}\}_\},_\N{\$uid};}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3Successfully_added_\$uid_to_group_name_\$gid\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_Assume_have_already_bound_to_server_as_admin.}}
\CE{}\L{\LB{\Proc{create\_group}\K{sub}_\V{create\_group}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$cn},_\N{\$gidNumber},_@\V{memberlist}_)_=_@\V{\_};}}
\L{\LB{____\K{if}_(_\V{exists}_\N{\$group}\V{\_byname}\{\N{\$cn}\}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_This_is_no_major_problem_if_the_group_already_exists.}}
\CE{}\L{\LB{________\K{warn}_\S{}\3group_\$cn_exists_with_group_number_\$group\_byname\{\$cn\}\3\SE{};}}
\L{\LB{________\K{return}_\N{0};}}
\L{\LB{____\}}}
\L{\LB{____\K{if}_(_\V{exists}_\N{\$group}\V{\_bynumber}\{\N{\$gidNumber}\}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\2n\2n\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\3\SE{};}}
\L{\LB{_________\K{warn}_\S{}\3PROBLEM:_group_\$cn_exists_with_group_number_\$gidNumber,_\3\SE{},}}
\L{\LB{____________\S{}\3but_not_in_\2\%group\_byname!\3\SE{};}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\2n\2n\3\SE{};}}
\L{\LB{_________\K{return}_\N{0};}}
\L{\LB{____\}}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$resu$\ell$t};}}
\L{\LB{____\K{if}_(_@\V{memberlist}_)}}
\L{\LB{____\{}}
\L{\LB{________\N{\$resu$\ell$t}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{add}(}}
\L{\LB{_________________________________\V{dn}_=\>_\S{}\3cn=\$cn,ou=Group,\$base\3\SE{},}}
\L{\LB{_________________________________\V{attr}_=\>_[}}
\L{\LB{__________________________________________\V{cn}_=\>_\S{}\3\$cn\3\SE{},}}
\L{\LB{__________________________________________\V{objectClass}_=\>_[_\S{}\4posixGroup\4\SE{},}}
\L{\LB{___________________________________________________________\S{}\4top\4\SE{}_],}}
\L{\LB{__________________________________________\V{userPassword}_=\>_\S{}\4\{crypt\}x\4\SE{},}}
\L{\LB{__________________________________________\V{gidNumber}_=\>_\N{\$gidNumber},}}
\L{\LB{__________________________________________\V{memberUid}_=\>_[_@\V{memberlist}_],}}
\L{\LB{_________________________________________]}}
\L{\LB{________________________________);}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\N{\$resu$\ell$t}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{add}(}}
\L{\LB{_________________________________\V{dn}_=\>_\S{}\3cn=\$cn,ou=Group,\$base\3\SE{},}}
\L{\LB{_________________________________\V{attr}_=\>_[}}
\L{\LB{__________________________________________\V{cn}_=\>_\S{}\3\$cn\3\SE{},}}
\L{\LB{__________________________________________\V{objectClass}_=\>_[_\S{}\4posixGroup\4\SE{},}}
\L{\LB{___________________________________________________________\S{}\4top\4\SE{}_],}}
\L{\LB{__________________________________________\V{userPassword}_=\>_\S{}\4\{crypt\}x\4\SE{},}}
\L{\LB{__________________________________________\V{gidNumber}_=\>_\N{\$gidNumber},}}
\L{\LB{_________________________________________]}}
\L{\LB{________________________________);}}
\L{\LB{____\}}}
\L{\LB{____\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_If_we_get_here,_it_really_is_a_problem,_since_the_hash_should_have}}
\CE{}\L{\LB{\C{}________\#_indicated_if_there_was_already_an_entry_for_this_group.}}
\CE{}\L{\LB{\C{}________\#_Would_need_to_invesigate:}}
\CE{}\L{\LB{________\K{warn}_\S{}\3PROBLEM:_failed_to_add_entry:_\3\SE{},_\N{\$resu$\ell$t}\-\!\>\V{error};}}
\L{\LB{________\K{return}_\N{0};}}
\L{\LB{____\}}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Successfully_created_group_cn=\$cn,ou=Group,\$base_with_\3\SE{},}}
\L{\LB{________\S{}\3GIDnumber_=_\$gidNumber\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{}}
\L{\LB{____\N{\$group}\V{\_byname}\{\N{\$cn}\}_=_\N{\$gidNumber};}}
\L{\LB{____\N{\$group}\V{\_bynumber}\{\N{\$gidNumber}\}\{\S{}\4gid\4\SE{}\}_=_\N{\$cn};}}
\L{\LB{____\N{\$group}\V{\_bynumber}\{\N{\$gidNumber}\}\{\S{}\4members\4\SE{}\}_=_[_@\V{memberlist}_];}}
\L{\LB{____\K{return}_\N{1};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{create\_basic\_groups}()}}
\L{\LB{\{}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$group}_(_(_\S{}\4students\4\SE{},_\S{}\4year1\4\SE{},_\S{}\4year2\4\SE{},_\S{}\4year3\4\SE{}_)_)}}
\L{\LB{____\{}}
\L{\LB{________\V{create\_group}(_\N{\$group},_\V{get\_next\_gid\_number}()_);}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{delete\_group}\K{sub}_\V{delete\_group}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$gid}_=_\K{shift};}}
\L{\LB{____\V{my}_\N{\$dn}_=_\S{}\3cn=\$gid,ou=Group,\$base\3\SE{};}}
\L{\LB{____\V{my}_\N{\$resu$\ell$t}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\K{delete}(_\N{\$dn}_);}}
\L{\LB{____\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_Don\4t_call_this_unless_need_to!}}
\CE{}\L{\LB{________\K{warn}_\S{}\3PROBLEM:_Failed_to_delete_\$dn\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3Successfully_deleted_\$dn\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{\C{}________\#_Remove_this_entry_from_both_hashes:}}
\CE{}\L{\LB{________\V{my}_\N{\$gidNumber}_=_\N{\$group}\V{\_byname}\{\N{\$gid}\};}}
\L{\LB{________\K{delete}_\N{\$group}\V{\_byname}\{\N{\$gid}\};}}
\L{\LB{________\K{delete}_\N{\$group}\V{\_bynumber}\{\N{\$gidNumber}\};}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_Assume_have_already_bound_to_server_as_admin.}}
\CE{}\L{\LB{\C{}\#_should_be_able_to_be_called_whether_entry_exists_or_not.}}
\CE{}\L{\LB{\Proc{create\_auto\_home\_entry}\K{sub}_\V{create\_auto\_home\_entry}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$uid}_=_\K{shift};}}
\L{\LB{____\V{my}_\N{\$basedn}_=_\S{}\3ou=auto.home,\$base\3\SE{};}}
\L{\LB{____\V{my}_\N{\$autohome}\V{\_search}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{search}(}}
\L{\LB{_____________________________________________\V{base}_=\>_\N{\$basedn},}}
\L{\LB{_____________________________________________\V{scope}_=\>_\S{}\4one\4\SE{},}}
\L{\LB{_____________________________________________\V{filter}_=\>_\S{}\3(cn=\$uid)\3\SE{},}}
\L{\LB{___________________________________________);}}
\L{\LB{____\K{warn}_\S{}\3Cannot_search_for_all_ICT_\$uid\2\4s_auto.home_entry_\3\SE{}}}
\L{\LB{________._\S{}\3in_ICT_LDAP_server:_\3\SE{},}}
\L{\LB{________\N{\$autohome}\V{\_search}\-\!\>\V{error}(),_\S{}\3\2n\3\SE{}_\K{if}_\N{\$autohome}\V{\_search}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$wanted}\V{\_automount}}}
\L{\LB{________=_\S{}\3\$automount\_options_\$nfs\_server:\$home\_dir\_base\1\$uid\3\SE{};}}
\L{\LB{____\K{if}_(_\N{\$autohome}\V{\_search}\-\!\>\V{count}()_==_\N{1}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_We_already_have_an_auto.home_entry_for_this_user.}}
\CE{}\L{\LB{\C{}________\#_Make_sure_the_automountInformation_is_correct,_write_back_if_not}}
\CE{}\L{\LB{________\V{my}_\N{\$entry}_=_\N{\$autohome}\V{\_search}\-\!\>\V{pop\_entry};}}
\L{\LB{________\K{if}_(_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4automountInformation\4\SE{}_)_\V{ne}_\N{\$wanted}\V{\_automount}_)}}
\L{\LB{________\{}}
\L{\LB{____________\N{\$entry}\-\!\>\V{replace}(_\S{}\4automountInformation\4\SE{}_=\>_\N{\$wanted}\V{\_automount}_);}}
\L{\LB{____________\V{my}_\N{\$resu$\ell$t}_=_\N{\$entry}\-\!\>\V{update}(_\N{\$$\ell$dap}\V{\_ict}_);}}
\L{\LB{____________\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____________\{}}
\L{\LB{________________\K{warn}_\S{}\3PROBLEM:_failed_to_update_auto.home_for_\$uid:_\3\SE{},}}
\L{\LB{____________________\N{\$resu$\ell$t}\-\!\>\V{error},_\S{}\3\2n\3\SE{};}}
\L{\LB{____________\}}}
\L{\LB{____________\K{else}}}
\L{\LB{____________\{}}
\L{\LB{________________\V{my}_\N{\$dn}_=_\N{\$entry}\-\!\>\V{dn}();}}
\L{\LB{________________\K{print}_\V{OUTPUT}_\S{}\3Successfully_updated_\$dn\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____________\}}}
\L{\LB{________\}}}
\L{\LB{________\K{else}}}
\L{\LB{________\{}}
\L{\LB{____________\K{print}_\V{OUTPUT}_\S{}\3\$uid_already_has_a_good_auto.home_entry\2n\3\SE{};}}
\L{\LB{________\}}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_\N{\$autohome}\V{\_search}\-\!\>\V{count}()_==_\N{0}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_Create_and_add_a_new_auto.home_entry:}}
\CE{}\L{\LB{________\V{my}_\N{\$dn}_=_\S{}\3cn=\$uid,\$basedn\3\SE{};}}
\L{\LB{________\V{my}_\N{\$attributes}_=_[}}
\L{\LB{__________________________\V{objectClass}_=\>_\S{}\4automount\4\SE{},}}
\L{\LB{__________________________\V{cn}_=\>_\N{\$uid},}}
\L{\LB{__________________________\V{automountInformation}_=\>_\N{\$wanted}\V{\_automount},}}
\L{\LB{_________________________];}}
\L{\LB{________\V{my}_\N{\$resu$\ell$t}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{add}(_\N{\$dn},_\V{attrs}_=\>_[_@\N{\$attributes}_]_);}}
\L{\LB{________\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{________\{}}
\L{\LB{____________\K{warn}_\S{}\3PROBLEM:_failed_to_add_new_auto.home_for_\$uid:_\3\SE{},}}
\L{\LB{________________\N{\$resu$\ell$t}\-\!\>\V{error},_\S{}\3\2n\3\SE{};}}
\L{\LB{________\}}}
\L{\LB{________\K{else}}}
\L{\LB{________\{}}
\L{\LB{____________\K{print}_\V{OUTPUT}_\S{}\3Successfully_created_\$dn\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{________\}}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_more_than_one_auto.home_entry_for_\$uid!!\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\V{use}_\V{File}::\V{Copy};}}
\L{\LB{}}
\L{\LB{\C{}\#_Note:_this_should_work_even_if_the_directory_has_been_created.}}
\CE{}\L{\LB{\C{}\#_It_could_be_owned_by_the_wrong_uidNumber_or_gidNumber.}}
\CE{}\L{\LB{\Proc{create\_home\_directory}\K{sub}_\V{create\_home\_directory}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$uid},_\N{\$uidNumber}_)_=_@\V{\_};}}
\L{\LB{____(_\K{mkdir}(_\S{}\3\$home\_dir\_base\1\$uid\3\SE{},_\N{0711}_)}}
\L{\LB{______\V{or}_\K{warn}_\S{}\3cannot_make_\$home\_dir\_base\1\$uid:_\$!\3\SE{}_)}}
\L{\LB{________\K{unless}_\-\V{d}_\S{}\3\$home\_dir\_base\1\$uid\3\SE{};}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$copy}\V{\_error}_=_\N{0};}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$fi$\ell$e}_(_\K{split}_\1\2\K{s}+\1,_{`}\V{echo}_\1\V{etc}\1\V{skel}\1.[\5.]\*{`}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{next}_\K{if}_\N{\$fi$\ell$e}_\V{eq}_\S{}\3\1etc\1skel\1.kde\3\SE{};}}
\L{\LB{\C{}________\#_Kinder_to_only_copy_these_files_if_they_don\4t_exist:}}
\CE{}\L{\LB{________\K{unless}_(_\-\V{f}_\S{}\3\$home\_dir\_base\1\$uid\1\$file\3\SE{}_)}}
\L{\LB{________\{}}
\L{\LB{____________\K{print}_\V{OUTPUT}_\S{}\3Copying_\4\$file\4_to_\$home\_dir\_base\1\$uid.\,.\,.\2n\3\SE{}}}
\L{\LB{________________\K{if}_\N{\$debug};}}
\L{\LB{____________\V{copy}(_\N{\$fi$\ell$e},_\S{}\3\$home\_dir\_base\1\$uid\3\SE{}_)_\V{or}_\N{\$copy}\V{\_error}_=_\N{1}}}
\L{\LB{________\}}}
\L{\LB{____\}}}
\L{\LB{\C{}____\#_system(_\3cp_-a_\1etc\1skel\1.[\5.]\*_\$home\_dir\_base\1\$uid_\>_\1dev\1null_2\>\&1\3_)}}
\CE{}\L{\LB{\C{}____\#___==_0}}
\CE{}\L{\LB{________\K{warn}_\S{}\3Couldn\4t_copy_skel_dot_files_to_\$home\_dir\_base\1\$uid\2n\3\SE{}}}
\L{\LB{____________\K{if}_\N{\$copy}\V{\_error};}}
\L{\LB{\C{}____\#_The_non-dot_files_are_directories,_so_better_to_use_cp_-a:}}
\CE{}\L{\LB{\C{}____\#_NOTE:_this_will_destroy_people\4s_carefully_crafted_desktop_settings!}}
\CE{}\L{\LB{\C{}____\#_If_that\4s_a_problem,_test_if_files_exist_before_copying.}}
\CE{}\L{\LB{____\K{system}(_\S{}\3cp_\-ua_\1etc\1skel\1\*_\1etc\1skel\1.kde_\$home\_dir\_base\1\$uid_\>_\1dev\1null_2\>\&1\3\SE{}_)_==_\N{0}}}
\L{\LB{________\V{or}_\K{warn}_\S{}\3Couldn\4t_copy_skel_non\-dot_files_and_.kde_directory_to_\$home\_dir\_base\1\$uid\2n\3\SE{};}}
\L{\LB{\C{}____\#_system(_\3chown\3,_\3-R\3,_\3\$uidNumber.\$uidNumber\3,_\3\$home\_dir\_base\1\$uid\3,}}
\CE{}\L{\LB{\C{}____\#_________\3\>_\1dev\1null_2\>\&1\3_)_==_0_}}
\CE{}\L{\LB{\C{}____\#_changing_the_ownership_should_not_hurt_any_except_those_who_are_working}}
\CE{}\L{\LB{\C{}____\#_on_a_group_project.}}
\CE{}\L{\LB{____\K{system}(_\S{}\3chown_\-R_\$uidNumber.\$uidNumber_\$home\_dir\_base\1\$uid_\3\SE{}}}
\L{\LB{____________._\S{}\3\>_\1dev\1null_2\>\&1\3\SE{}_)_==_\N{0}_}}
\L{\LB{________\V{or}_\K{warn}_\S{}\3Could_let_\$uidNumber_=_\$uid_own_\$home\_dir\_base\1\$uid\2n\3\SE{};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{\dots l\_group\_info\_from\_ict\_server}\K{sub}_\V{read\_all\_group\_info\_from\_ict\_server}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$basedn}_=_\S{}\3ou=Group,\$base\3\SE{};}}
\L{\LB{____\V{my}_\N{\$group}\V{\_search}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{search}(}}
\L{\LB{_________________________________________\V{base}_=\>_\N{\$basedn},}}
\L{\LB{_________________________________________\V{scope}_=\>_\S{}\3one\3\SE{},}}
\L{\LB{_________________________________________\V{filter}_=\>_\S{}\3(cn=\*)\3\SE{}}}
\L{\LB{________________________________________);}}
\L{\LB{}}
\L{\LB{____\K{die}_\S{}\3Cannot_search_for_all_ICT_groups_in_ICT_LDAP_server_\3\SE{},}}
\L{\LB{________\S{}\3(probably_increasing_sizelimit_in_\1etc\1openldap\1slapd.conf_\3\SE{},}}
\L{\LB{________\S{}\3will_help):_\3\SE{},}}
\L{\LB{________\N{\$group}\V{\_search}\-\!\>\V{error}(),_\S{}\3\2n\3\SE{}_\K{if}_\N{\$group}\V{\_search}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Found_\3\SE{},_\N{\$group}\V{\_search}\-\!\>\V{count}(),}}
\L{\LB{____\S{}\3_group_entries_in_ICT_server.\2n\3\SE{};}}
\L{\LB{____}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$entry}_(_\N{\$group}\V{\_search}\-\!\>\V{all\_entries}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{my}_\N{\$group}\V{\_name}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4cn\4\SE{}_)}}
\L{\LB{____________\|\,\|_\K{warn}_\S{}\3cannot_get_group_name:_\$!\3\SE{};}}
\L{\LB{________\V{my}_\N{\$group}\V{\_number}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4gidNumber\4\SE{}_)}}
\L{\LB{____________\|\,\|_\K{warn}_\S{}\3cannot_get_group_number:_\$!\3\SE{};}}
\L{\LB{________\V{my}_@\V{members}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4memberUid\4\SE{}_);}}
\L{\LB{________\K{print}_\V{OUTPUT}}}
\L{\LB{____________\S{}\3gid=\$group\_name,\2tgidNumber=\$group\_number,\2tmembers=\3\SE{}}}
\L{\LB{____________._\K{join}(_\S{}\3,_\3\SE{},_@\V{members}_)_._\S{}\3\2n\3\SE{};}}
\L{\LB{________\N{\$group}\V{\_byname}\{\N{\$group}\V{\_name}\}_=_\N{\$group}\V{\_number};}}
\L{\LB{________\N{\$group}\V{\_bynumber}\{\N{\$group}\V{\_number}\}\{\S{}\4gid\4\SE{}\}_=_\N{\$group}\V{\_name};}}
\L{\LB{________\N{\$group}\V{\_bynumber}\{\N{\$group}\V{\_number}\}\{\S{}\4members\4\SE{}\}_=_[_@\V{members}_];}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{\dots all\_uid\_numbers\_get\_greatest}\K{sub}_\V{read\_all\_uid\_numbers\_get\_greatest}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$max}\V{\_uid\_number}_=_\N{0};}}
\L{\LB{____\V{my}_\N{\$basedn}_=_\S{}\3ou=People,\$base\3\SE{};}}
\L{\LB{____\V{my}_\N{\$useridnum}\V{\_search}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{search}(}}
\L{\LB{_____________________________________________\V{base}_=\>_\N{\$basedn},}}
\L{\LB{_____________________________________________\V{scope}_=\>_\S{}\3one\3\SE{},}}
\L{\LB{_____________________________________________\V{filter}_=\>_\S{}\3(cn=\*)\3\SE{},}}
\L{\LB{_____________________________________________\V{attrs}_=\>_[_\S{}\4uidNumber\4\SE{}_],}}
\L{\LB{____________________________________________);}}
\L{\LB{}}
\L{\LB{____\K{warn}_\S{}\3Cannot_search_for_all_ICT_userid_numbers_in_ICT_LDAP_server:_\3\SE{},}}
\L{\LB{________\N{\$useridnum}\V{\_search}\-\!\>\V{error}(),_\S{}\3\2n\3\SE{}_\K{if}_\N{\$useridnum}\V{\_search}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Found_\3\SE{},_\N{\$useridnum}\V{\_search}\-\!\>\V{count}(),}}
\L{\LB{____\S{}\3_uid_entries_in_ICT_server.\2n\3\SE{};}}
\L{\LB{}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$entry}_(_\N{\$useridnum}\V{\_search}\-\!\>\V{entries}()_)}}
\L{\LB{____\{}}
\L{\LB{________\N{\$max}\V{\_uid\_number}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uidNumber\4\SE{}_)}}
\L{\LB{____________\K{if}__\N{\$max}\V{\_uid\_number}_\<_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uidNumber\4\SE{}_);}}
\L{\LB{____\}}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Max_UID_number_=_\$max\_uid\_number_in_ICT_server\2n\3\SE{};}}
\L{\LB{____\K{return}_\N{\$max}\V{\_uid\_number};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{bind\_as\_admin\_to\_local\_server}\K{sub}_\V{bind\_as\_admin\_to\_local\_server}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$admin}\V{\_password\_file}_=_\S{}\3\1root\1ldapaccounts\1ldap\-admin\-password\3\SE{};}}
\L{\LB{____\K{open}_\V{PW},_\S{}\3\<_\$admin\_password\_file\3\SE{}_\V{or}_\K{die}_\S{}\3cannot_open_\2\3\$admin\_password\_file\2\3:_\$!\3\SE{};}}
\L{\LB{____\V{my}_\N{\$adminpassword}_=_\<\V{PW}\>;}}
\L{\LB{____\V{chomp}_\N{\$adminpassword};}}
\L{\LB{____\K{close}_\V{PW};}}
\L{\LB{____\N{\$mesg}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\K{bind}(}}
\L{\LB{____________________________\V{dn}_=\>_\S{}\3cn=admin,\$base\3\SE{},}}
\L{\LB{____________________________\V{password}_=\>_\S{}\3\$adminpassword\3\SE{},}}
\L{\LB{____________________________\V{version}_=\>_\N{3}}}
\L{\LB{___________________________);}}
\L{\LB{____\K{die}_\S{}\3Failed_to_bind_as_admin_to_ICT_ldap_server:_\3\SE{},_\N{\$mesg}\-\!\>\V{error}(),_\S{}\3\2n\3\SE{}}}
\L{\LB{________\K{if}_\N{\$mesg}\-\!\>\V{code}();}}
\L{\LB{\C{}____\#_Failed_to_bind_as_admin_to_ICT_ldap_server:_I\1O_Error}}
\CE{}\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Now_bound_as_\2\3cn=admin,\$base\2\3\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{make\_groups\_and\_home\_directory}\K{sub}_\V{make\_groups\_and\_home\_directory}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$uid},_\N{\$uidNumber},_@\V{secondary\_groups}_)_=_@\V{\_};}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3\2@secondary\_groups:_\3\SE{},_\K{join}(_\S{}\4,_\4\SE{},_@\V{secondary\_groups}_),_\S{}\3\2n\3\SE{};}}
\L{\LB{\C{}____\#_Delete_the_primary_group_if_it_exists_with_a_gidNumber_different_from}}
\CE{}\L{\LB{\C{}____\#_that_in_the_Person_entry_for_this_user.}}
\CE{}\L{\LB{____\V{delete\_group}(_\N{\$uid}_)}}
\L{\LB{________\K{if}_\V{exists}_\N{\$group}\V{\_byname}\{\N{\$uid}\}}}
\L{\LB{____________\V{and}_\V{not}_\V{exists}_\N{\$group}\V{\_bynumber}\{\N{\$uidNumber}\};}}
\L{\LB{\C{}____\#_create_the_primary_private_user_group_if_it\4s_not_already_there:}}
\CE{}\L{\LB{____\V{create\_group}(_\N{\$uid},_\N{\$uidNumber},_()_)_\K{if}_\V{not}_\V{exists}_\N{\$group}\V{\_byname}\{\N{\$uid}\};}}
\L{\LB{____\V{create\_auto\_home\_entry}(_\N{\$uid}_);}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$group}_(_@\V{secondary\_groups}_)\V{\#}_(_\S{}\4students\4\SE{},_\N{\$course},_\S{}\4year\4\SE{}_._\N{\$year}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{add\_uid\_to\_group}(_\N{\$uid},_\N{\$group}_);}}
\L{\LB{____\}}}
\L{\LB{____\V{create\_home\_directory}(_\N{\$uid},_\N{\$uidNumber}_);}}
\L{\LB{\C{}____\#_TODO:}}
\CE{}\L{\LB{\C{}____\#_Write_code_to_remove_user_from_wrong_(old)_groups.}}
\CE{}\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_Do_not_touch_password,_uidNumber_or_gidNumber}}
\CE{}\L{\LB{\C{}\#_Will_do_a_replace_operation.}}
\CE{}\L{\LB{\Proc{update\_user}\K{sub}_\V{update\_user}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$entry},_@\V{secondary\_groups}_)_=_@\V{\_};}}
\L{\LB{____\N{\$entry}\-\!\>\V{changetype}(_\S{}\4replace\4\SE{}_);}}
\L{\LB{____\V{my}_\N{\$dn}_=_\N{\$entry}\-\!\>\V{dn};}}
\L{\LB{____\V{my}_\N{\$uid}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uid\4\SE{}_);}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$resu$\ell$t}_=_\N{\$entry}\-\!\>\V{update}(_\N{\$$\ell$dap}\V{\_ict}_);}}
\L{\LB{____\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_failed_to_update_\$dn:_\3\SE{},_\N{\$resu$\ell$t}\-\!\>\V{error};}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3successful_update_of_\$dn:\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{____\N{\$entry}\-\!\>\K{dump}()_\K{if}_\N{\$debug};}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$uidNumber}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uidNumber\4\SE{}_);}}
\L{\LB{____\V{make\_groups\_and\_home\_directory}(_\N{\$uid},_\N{\$uidNumber},_@\V{secondary\_groups}_);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_OLD_CODE:}}
\CE{}\L{\LB{\C{}\#_If_the_\$passwd_parameter_is_not_empty,_will_use_that_as_the_new_password}}
\CE{}\L{\LB{\C{}\#_.\,.\,.But_only_if_\$gen\_new\_password_is_true.}}
\CE{}\L{\LB{\C{}\#_sub_update\_user}}
\CE{}\L{\LB{\C{}\#_\{}}
\CE{}\L{\LB{\C{}\#_____my_(_\$uid,_\$cn,_\$mail,_\$one\_ict\_user,_\$passwd,_@secondary\_groups_)_=_@\_;}}
\CE{}\L{\LB{\C{}\#_____my_\$entry_=_\$one\_ict\_user-\!\>pop\_entry;}}
\CE{}\L{\LB{\C{}\#_____my_\$dn_=_\$entry-\!\>dn;}}
\CE{}\L{\LB{\C{}\#_____my_\$old\_cn_=_\$entry-\!\>get\_value(_\4cn\4_);}}
\CE{}\L{\LB{\C{}\#_____my_\$changed_=_0;}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_\3Checking_dn:_\$dn,_cn=\$cn,_\2\$old\_cn=\$old\_cn\2n\3;}}
\CE{}\L{\LB{\C{}\#_____if_(_\$old\_cn_ne_\$cn_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\$changed_=_1;}}
\CE{}\L{\LB{\C{}\#_________my_(_\$cn,_\$sn,_\$givenName_)}}
\CE{}\L{\LB{\C{}\#_____________=_get\_user\_names(_\$cn_);}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>replace(}}
\CE{}\L{\LB{\C{}\#_________________________\4cn\4_=\>_\$cn,}}
\CE{}\L{\LB{\C{}\#_________________________\4gecos\4_=\>_\$cn,}}
\CE{}\L{\LB{\C{}\#_________________________\4sn\4_=\>_\$sn,}}
\CE{}\L{\LB{\C{}\#_________________________\4givenName\4_=\>_\$givenName}}
\CE{}\L{\LB{\C{}\#________________________);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT}}
\CE{}\L{\LB{\C{}\#_____________\3updating_names_for_\$uid:_cn=\$cn,_sn=\$sn,_givenName=\$givenName_\2n\3;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____if_(_\$gen\_new\_password_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\$changed_=_1;}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3updating_password_for_\$uid\2n\3;}}
\CE{}\L{\LB{\C{}\#_________my_(_\$plain\_text\_passwd,_\$md5\_hash\_passwd_)_=_gen\_password(_\$passwd_);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3UID:_\$uid;_\3,}}
\CE{}\L{\LB{\C{}\#_____________\3\2\3\$plain\_text\_passwd\2\3,_\2\3\$md5\_hash\_passwd\2\3\2n\3}}
\CE{}\L{\LB{\C{}\#_________________if_\$debug;}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>replace(_userPassword_=\>_\$md5\_hash\_passwd_);}}
\CE{}\L{\LB{\C{}\#_________print_PASSWD\_INFO_\3\$uid:\$plain\_text\_passwd:\$md5\_hash\_passwd\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\$passwd\_dbm\_hash\{\$uid\}_=_\3\$plain\_text\_passwd:\$md5\_hash\_passwd\3;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____if_(_\$entry-\!\>get\_value(_\4mail\4_)_ne_\$mail_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\$changed_=_1;}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3updating_\$mail_for_\$uid\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>replace(}}
\CE{}\L{\LB{\C{}\#_________________________\4mail\4_=\>_\$entry-\!\>get\_value(_\4mail\4_)}}
\CE{}\L{\LB{\C{}\#________________________);}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____if_(_\$entry-\!\>get\_value(_\4homeDirectory\4_)_ne_\3\$home\_dir\_base\1\$uid\3_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\$changed_=_1;}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3updating_home_directory_for_\$uid\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>replace(}}
\CE{}\L{\LB{\C{}\#_________________________\4homeDirectory\4_=\>_\3\$home\_dir\_base\1\$uid\3}}
\CE{}\L{\LB{\C{}\#________________________);}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____if_(_\$changed_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________my_\$result_=_\$entry-\!\>update(_\$ldap\_ict_);}}
\CE{}\L{\LB{\C{}\#_________if_(_\$result-\!\>code_)}}
\CE{}\L{\LB{\C{}\#_________\{}}
\CE{}\L{\LB{\C{}\#_____________warn_\3PROBLEM:_failed_to_update_\$dn:_\3,_\$result-\!\>error;}}
\CE{}\L{\LB{\C{}\#_________\}}}
\CE{}\L{\LB{\C{}\#_________else}}
\CE{}\L{\LB{\C{}\#_________\{}}
\CE{}\L{\LB{\C{}\#_____________print_OUTPUT_\3successful_update_of_\$dn:\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\}}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>dump()_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____my_\$uidNumber_=_\$entry-\!\>get\_value(_\4uidNumber\4_);}}
\CE{}\L{\LB{\C{}\#_____make\_groups\_and\_home\_directory(_\$uid,_\$uidNumber,_@secondary\_groups_);}}
\CE{}\L{\LB{\C{}\#_\}}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_The_responsibility_for_the_attributes_being_correct_is_with_the_callers.}}
\CE{}\L{\LB{\C{}\#_This_includes_the_dn,_the_names,_etc.}}
\CE{}\L{\LB{\C{}\#_This_routine_determines_the_uidNumber_and_gidNumber_only.}}
\CE{}\L{\LB{\C{}\#_if_\$passwd_is_an_empty_string,_then_generate_password,}}
\CE{}\L{\LB{\C{}\#_else_assume_this_is_a_plain_text_password,_and_generate_MD5_password.}}
\CE{}\L{\LB{\Proc{add\_user}\K{sub}_\V{add\_user}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$entry},_\N{\$passwd},_@\V{secondary\_groups}_)_=_@\V{\_};}}
\L{\LB{____\V{my}_\N{\$dn}_=_\N{\$entry}\-\!\>\V{dn};}}
\L{\LB{____\V{my}_(_\N{\$uidNumber},_\N{\$gidNumber}_);}}
\L{\LB{____\K{do}}}
\L{\LB{____\{}}
\L{\LB{________\N{\$uidNumber}_=_\N{\$gidNumber}_=_\V{get\_next\_uid\_number}();}}
\L{\LB{____\}_\K{while}_(_\V{exists}_\N{\$group}\V{\_bynumber}\{\N{\$uidNumber}\}_);}}
\L{\LB{____\V{my}_(_\N{\$p$\ell$ain}\V{\_text\_passwd},_\N{\$md5}\V{\_hash\_passwd}_)_=_\V{gen\_password}(_\N{\$passwd}_);}}
\L{\LB{____\V{my}_\N{\$uid}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uid\4\SE{}_);}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3UID:_\$uid;_UIDn:_\$uidNumber;_GID:_\$gidNumber;_\3\SE{},}}
\L{\LB{________\S{}\3\2\3\$plain\_text\_passwd\2\3,_\2\3\$md5\_hash\_passwd\2\3\2n\3\SE{}}}
\L{\LB{________\K{if}_\N{\$debug};}}
\L{\LB{____\N{\$entry}\-\!\>\V{replace}(_\V{userPassword}_=\>_\N{\$md5}\V{\_hash\_passwd}_);}}
\L{\LB{____\N{\$entry}\-\!\>\V{changetype}(_\S{}\4add\4\SE{}_);}}
\L{\LB{____\V{my}_\N{\$resu$\ell$t}_=_\N{\$entry}\-\!\>\V{update}(_\N{\$$\ell$dap}\V{\_ict}_);}}
\L{\LB{____\K{if}_(_\N{\$resu$\ell$t}\-\!\>\V{code}_)}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_failed_to_add_user_entry_for_\$dn:_\3\SE{},_\N{\$resu$\ell$t}\-\!\>\V{error}}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3Successfully_created_entry_for_\$dn\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____\}}}
\L{\LB{____\K{print}_\V{PASSWD\_INFO}_\S{}\3\$uid:\$plain\_text\_passwd:\$md5\_hash\_passwd\2n\3\SE{};}}
\L{\LB{____\N{\$passwd}\V{\_dbm\_hash}\{\N{\$uid}\}_=_\S{}\3\$plain\_text\_passwd:\$md5\_hash\_passwd\3\SE{};}}
\L{\LB{____\V{make\_groups\_and\_home\_directory}(_\N{\$uid},_\N{\$uidNumber},_@\V{secondary\_groups}_);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_OLD_CODE:}}
\CE{}\L{\LB{\C{}\#_sub_add\_user}}
\CE{}\L{\LB{\C{}\#_\{}}
\CE{}\L{\LB{\C{}\#_____my_(_\$uid,_\$cn,_\$mail,_\$passwd,_@secondary\_groups_)_=_@\_;}}
\CE{}\L{\LB{\C{}\#_____my_\$dn_=_\3uid=\$uid,ou=People,\$base\3;}}
\CE{}\L{\LB{\C{}\#_____my_(_\$uidNumber,_\$gidNumber_);}}
\CE{}\L{\LB{\C{}\#_____do}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\$uidNumber_=_\$gidNumber_=_get\_next\_uid\_number();}}
\CE{}\L{\LB{\C{}\#_____\}_while_(_exists_\$group\_bynumber\{\$uidNumber\}_);}}
\CE{}\L{\LB{\C{}\#_____my_(_\$sn,_\$givenName_);}}
\CE{}\L{\LB{\C{}\#_____(_\$cn,_\$sn,_\$givenName_)_=_get\_user\_names(_\$cn_);}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_\3cn=\$cn,_sn=\$sn,_givenName=\$givenName\2n\3_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____my_(_\$plain\_text\_passwd,_\$md5\_hash\_passwd_)_=_gen\_password(_\$passwd_);}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_\3UID:_\$uid;_UIDn:_\$uidNumber;_GID:_\$gidNumber;_\3,}}
\CE{}\L{\LB{\C{}\#_________\3\2\3\$plain\_text\_passwd\2\3,_\2\3\$md5\_hash\_passwd\2\3\2n\3}}
\CE{}\L{\LB{\C{}\#_________if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____my_\$attributes_=_[}}
\CE{}\L{\LB{\C{}\#_______________________cn_=\>_\$cn,}}
\CE{}\L{\LB{\C{}\#_______________________sn_=\>_\$sn,}}
\CE{}\L{\LB{\C{}\#_______________________givenName_=\>_\$givenName,}}
\CE{}\L{\LB{\C{}\#_______________________uid_=\>_\$uid,}}
\CE{}\L{\LB{\C{}\#_______________________mail_=\>_\$mail,}}
\CE{}\L{\LB{\C{}\#_______________________gecos_=\>_\$cn,}}
\CE{}\L{\LB{\C{}\#_______________________objectClass_=\>_[}}
\CE{}\L{\LB{\C{}\#_______________________________________\3top\3,_\3person\3,}}
\CE{}\L{\LB{\C{}\#_______________________________________\3organizationalPerson\3,}}
\CE{}\L{\LB{\C{}\#_______________________________________\3inetOrgPerson\3,_\3account\3,}}
\CE{}\L{\LB{\C{}\#_______________________________________\3posixAccount\3,}}
\CE{}\L{\LB{\C{}\#_______________________________________\3kerberosSecurityObject\3,}}
\CE{}\L{\LB{\C{}\#______________________________________],}}
\CE{}\L{\LB{\C{}\#_______________________krbname_=\>_\3\$uid\2@\$kerberos\_realm\3,}}
\CE{}\L{\LB{\C{}\#_______________________loginShell_=\>_\3\1bin\1bash\3,}}
\CE{}\L{\LB{\C{}\#_______________________uidNumber_=\>_\$uidNumber,}}
\CE{}\L{\LB{\C{}\#_______________________gidNumber_=\>_\$uidNumber,}}
\CE{}\L{\LB{\C{}\#_______________________homeDirectory_=\>_\3\$home\_dir\_base\1\$uid\3,}}
\CE{}\L{\LB{\C{}\#_______________________userPassword_=\>_\$md5\_hash\_passwd,}}
\CE{}\L{\LB{\C{}\#______________________];}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_join(_\4\3,_\3\4,_@\$attributes_),_\3\2n\3_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____my_\$result_=_\$ldap\_ict-\!\>add(_\$dn,_attrs_=\>_[_@\$attributes_]_);}}
\CE{}\L{\LB{\C{}\#_____if_(_\$result-\!\>code_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________warn_\3PROBLEM:_failed_to_add_user_entry_for_\$dn:_\3,_\$result-\!\>error}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____else}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3Successfully_created_entry_for_\$dn\2n\3_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____print_PASSWD\_INFO_\3\$uid:\$plain\_text\_passwd:\$md5\_hash\_passwd\2n\3;}}
\CE{}\L{\LB{\C{}\#_____\$passwd\_dbm\_hash\{\$uid\}_=_\3\$plain\_text\_passwd:\$md5\_hash\_passwd\3;}}
\CE{}\L{\LB{\C{}\#_____make\_groups\_and\_home\_directory(_\$uid,_\$uidNumber,_@secondary\_groups_);}}
\CE{}\L{\LB{\C{}\#_\}}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Would_like_to_make_this_subroutine_apply_equally_well_to_staff_or_students.}}
\CE{}\L{\LB{\C{}\#_Is_it_better_to_make_all_modifications_to_the_entry_when_read_it_from_the}}
\CE{}\L{\LB{\C{}\#_source_or_when_write_it_to_the_target?}}
\CE{}\L{\LB{\C{}\#_Only_can_(easily)_tell_what_is_missing_when_read_the_source.}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Ignoring_changes_made_at_the_target_will_overwrite_changes_made_by_the_user.}}
\CE{}\L{\LB{\C{}\#_Very_nasty_behaviour.}}
\CE{}\L{\LB{\C{}\#_Solution:}}
\CE{}\L{\LB{\C{}\#_For_updates:_not_change_things_that_user_can_change.}}
\CE{}\L{\LB{\C{}\#_For_new_accounts,_there_is_no_problem_with_destroying_existing_data.}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_This_function_is_very_simple:}}
\CE{}\L{\LB{\C{}\#_Take_an_entry,_send_off_to_modify_routine_if_exists,}}
\CE{}\L{\LB{\C{}\#_else_send_to_add_routine_if_not_exist.}}
\CE{}\L{\LB{\C{}\#_This_routine_does_no_other_action.}}
\CE{}\L{\LB{\C{}\#_Note:_it_is_the_responsibility_of_the_caller_of_this_routine_to}}
\CE{}\L{\LB{\C{}\#_ensure_that_all_the_attributes_are_correct.}}
\CE{}\L{\LB{\C{}\#_This_includes_the_dn_itself.}}
\CE{}\L{\LB{\C{}\#_if_this_is_a_new_account,}}
\CE{}\L{\LB{\C{}\#________if_\$passwd_is_an_empty_string,_then}}
\CE{}\L{\LB{\C{}\#__________________generate_password_from_nothing,}}
\CE{}\L{\LB{\C{}\#________else}}
\CE{}\L{\LB{\C{}\#__________________assume_this_is_a_plain_text_password,_and}}
\CE{}\L{\LB{\C{}\#__________________generate_coresponding_MD5_password.}}
\CE{}\L{\LB{\C{}\#_Specificially,_if_this_is_an_update_to_existing_account,_never_touch}}
\CE{}\L{\LB{\C{}\#_password.}}
\CE{}\L{\LB{}}
\L{\LB{\Proc{add\_or\_update\_user}\K{sub}_\V{add\_or\_update\_user}}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$entry},_\N{\$passwd},_@\V{secondary\_groups}_)_=_@\V{\_};}}
\L{\LB{____\V{my}_\N{\$uid}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uid\4\SE{}_);}}
\L{\LB{____\V{my}_\N{\$one}\V{\_ict\_student}_=_\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{search}(}}
\L{\LB{____________________________________________\V{base}_=\>_\S{}\3ou=People,\$base\3\SE{},}}
\L{\LB{____________________________________________\V{scope}_=\>_\S{}\3one\3\SE{},}}
\L{\LB{____________________________________________\V{filter}_=\>_\S{}\3(uid=\$uid)\3\SE{}}}
\L{\LB{___________________________________________);}}
\L{\LB{____\K{if}_(_\N{\$one}\V{\_ict\_student}\-\!\>\V{code}()_)}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_Cannot_search_for_ICT_student_\$uid_in_ICT_LDAP_server:_\3\SE{},}}
\L{\LB{________\N{\$one}\V{\_ict\_student}\-\!\>\V{error}(),_\S{}\3\2n\3\SE{};}}
\L{\LB{________\K{return};}}
\L{\LB{____\}}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$count}\V{\_of\_entries\_retrieved}_=_\N{\$one}\V{\_ict\_student}\-\!\>\V{count}();}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3\2\$one\_ict\_student\-\!\>count()_=_\$count\_of\_entries\_retrieved\2n\3\SE{}}}
\L{\LB{________\K{if}_\N{\$debug};}}
\L{\LB{}}
\L{\LB{____\K{if}_(_\N{\$one}\V{\_ict\_student}\-\!\>\V{count}()_==_\N{1}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_The_student_already_has_an_entry_in_ICT_LDAP_server,}}
\CE{}\L{\LB{\C{}________\#_but_some_attributes_may_be_out_of_date.}}
\CE{}\L{\LB{\C{}________\#_Keep_the_current_GID_and_UID_numbers.__Do_not_change_the_password.}}
\CE{}\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3would_be_about_to_update_this_record:\2n\3\SE{};}}
\L{\LB{________\N{\$entry}\-\!\>\K{dump};}}
\L{\LB{\C{}________\#update\_user(_\$entry,_@secondary\_groups_);}}
\CE{}\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_\N{\$one}\V{\_ict\_student}\-\!\>\V{count}()_==_\N{0}_)}}
\L{\LB{____\{}}
\L{\LB{\C{}________\#_No_person_exists_with_\$uid_in_the_local_LDAP_server,}}
\CE{}\L{\LB{\C{}________\#_so_create_and_add_the_new_entry:}}
\CE{}\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3would_be_about_to_add_this_NEW_record:\2n\3\SE{};}}
\L{\LB{________\N{\$entry}\-\!\>\K{dump};}}
\L{\LB{\C{}________\#_add\_user(_\$entry,_\$passwd,_@secondary\_groups_);}}
\CE{}\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\K{warn}_\S{}\3PROBLEM:_\$uid_has_more_than_one_entry!!\2n\3\SE{};}}
\L{\LB{____\}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_OLD_CODE:}}
\CE{}\L{\LB{\C{}\#_sub_add\_or\_update\_user}}
\CE{}\L{\LB{\C{}\#_\{}}
\CE{}\L{\LB{\C{}\#_____my_(_\$uid,_\$cn,_\$mail,__\$passwd,_@secondary\_groups_)_=_@\_;}}
\CE{}\L{\LB{\C{}\#_____my_(_\$sn,_\$givenName_);}}
\CE{}\L{\LB{\C{}\#_____(_\$cn,_\$sn,_\$givenName_)_=_get\_user\_names(_\$cn_);}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_\3cn=\$cn,_sn=\$sn,_givenName=\$givenName\2n\3_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_____my_\$one\_ict\_student_=_\$ldap\_ict-\!\>search(}}
\CE{}\L{\LB{\C{}\#_____________________________________________base_=\>_\3ou=People,\$base\3,}}
\CE{}\L{\LB{\C{}\#_____________________________________________scope_=\>_\3one\3,}}
\CE{}\L{\LB{\C{}\#_____________________________________________filter_=\>_\3(uid=\$uid)\3}}
\CE{}\L{\LB{\C{}\#____________________________________________);}}
\CE{}\L{\LB{\C{}\#_____warn_\3PROBLEM:_Cannot_search_for_ICT_student_\$uid_in_ICT_LDAP_server:_\3,}}
\CE{}\L{\LB{\C{}\#_________\$one\_ict\_student-\!\>error(),_\3\2n\3_if_\$one\_ict\_student-\!\>code();}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____my_\$count\_of\_entries\_retrieved_=_\$one\_ict\_student-\!\>count();}}
\CE{}\L{\LB{\C{}\#_____print_OUTPUT_\3\2\$one\_ict\_student-\!\>count()_=_\$count\_of\_entries\_retrieved\2n\3}}
\CE{}\L{\LB{\C{}\#_________if_\$debug;}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____if_(_\$one\_ict\_student-\!\>count()_==_1_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\#_The_student_already_has_an_entry_in_ICT_LDAP_server,}}
\CE{}\L{\LB{\C{}\#_________\#_but_some_attributes_may_be_out_of_date.}}
\CE{}\L{\LB{\C{}\#_________\#_Keep_the_current_GID_and_UID_numbers.}}
\CE{}\L{\LB{\C{}\#_________update\_user(_\$uid,_\$cn,_\$mail,_\$one\_ict\_student,}}
\CE{}\L{\LB{\C{}\#______________________\$passwd,_@secondary\_groups_);}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____elsif_(_\$one\_ict\_student-\!\>count()_==_0_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________\#_No_person_exists_with_\$uid_in_the_local_LDAP_server,}}
\CE{}\L{\LB{\C{}\#_________\#_so_create_and_add_the_new_entry:}}
\CE{}\L{\LB{\C{}\#_________add\_user(_\$uid,_\$cn,_\$mail,_\$passwd,_@secondary\_groups_);}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____else}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________warn_\3PROBLEM:_\$uid_has_more_than_one_entry!!\2n\3;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_\}}}
\CE{}\L{\LB{}}
\L{\LB{\K{sub}_\V{set\_default\_classes}(\N{\$}\N{\$})}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$entry},_\N{\$student}\V{\_or\_staff}_)_=_@\V{\_};}}
\L{\LB{____\N{\$entry}\-\!\>\V{replace}(}}
\L{\LB{____________________\V{objectClass}_=\>_[}}
\L{\LB{____________________________________\S{}\3top\3\SE{},_\S{}\3person\3\SE{},}}
\L{\LB{____________________________________\S{}\3organizationalPerson\3\SE{},}}
\L{\LB{____________________________________\S{}\3inetOrgPerson\3\SE{},_\S{}\3account\3\SE{},}}
\L{\LB{____________________________________\S{}\3posixAccount\3\SE{},}}
\L{\LB{____________________________________\S{}\3kerberosSecurityObject\3\SE{},}}
\L{\LB{____________________________________\S{}\3institute\3\SE{},}}
\L{\LB{____________________________________\N{\$student}\V{\_or\_staff},}}
\L{\LB{___________________________________],}}
\L{\LB{_______________);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\C{}\#_The_difference_between_students_and_staff_is_(on_vtc_ldap_server):}}
\CE{}\L{\LB{\C{}\#_base_dn_of_staff____is_ou=ICT,ou=TY,_______o=vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#_base_dn_of_students_is_ou=ICT,ou=TY,ou=stu,o=vtc.edu.hk}}
\CE{}\L{\LB{\C{}\#_Both_have_a_filter_of_(uid=\*)}}
\CE{}\L{\LB{\C{}\#}}
\CE{}\L{\LB{\C{}\#_also_there_are_some_attributes_that_are_different.}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_Original_idea_was_to_read_each_entry,_delete_the_ones_we_don\4t_want,}}
\CE{}\L{\LB{\C{}\#_then_do_a_replace_operation.}}
\CE{}\L{\LB{\C{}\#_But_this_places_us_at_the_mercy_of_any_changes_to_the_VTC_ldap_server.}}
\CE{}\L{\LB{\C{}\#_Smarter:_just_get_the_values_we_want,_and_put_them_into_a_new_entry.}}
\CE{}\L{\LB{}}
\L{\LB{\K{sub}_\V{import\_and\_update\_student\_accounts\_from\_vtc\_ldap\_server}()}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$$\ell$dap}\V{\_vtc}_=_\V{Net}::\V{LDAP}\-\!\>\V{new}(_\S{}\3ldap.vtc.edu.hk\3\SE{}_)_\V{or}_\K{die}_\S{}\3\$@\3\SE{};}}
\L{\LB{____\V{my}_\N{\$mesg}\V{\_vtc}_=_\N{\$$\ell$dap}\V{\_vtc}\-\!\>\K{bind}(_\V{version}_=\>_\N{3}_);\C{}_\#_use_for_searches}}
\CE{}\L{\LB{}}
\L{\LB{____\K{die}_\S{}\3Failed_to_bind_to_VTC_ldap_server:_\3\SE{},_\N{\$mesg}\V{\_vtc}\-\!\>\V{code}(),_\S{}\3\2n\3\SE{}}}
\L{\LB{________\K{if}_\N{\$mesg}\V{\_vtc}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{____\V{my}_\N{\$basedn}_=_\S{}\3ou=ICT,ou=TY,ou=stu,o=vtc.edu.hk\3\SE{};}}
\L{\LB{____\V{my}_\N{\$a$\ell$$\ell$user}\V{\_search}_=_\N{\$$\ell$dap}\V{\_vtc}\-\!\>\V{search}(}}
\L{\LB{___________________________________\V{base}_=\>_\N{\$basedn},}}
\L{\LB{___________________________________\V{scope}_=\>_\S{}\3one\3\SE{},}}
\L{\LB{\C{}___________________________________\#_filter_=\>_\3(\|(department=CM)(department=ICT))\3,}}
\CE{}\L{\LB{___________________________________\V{filter}_=\>_\S{}\3(uid=\*)\3\SE{},}}
\L{\LB{___________________________________);}}
\L{\LB{}}
\L{\LB{____\K{warn}_\S{}\3PROBLEM:_Cannot_search_for_all_ICT_members_in_VTC_LDAP_server:_\3\SE{},}}
\L{\LB{______\N{\$a$\ell$$\ell$user}\V{\_search}\-\!\>\V{code}(),_\S{}\3\2n\3\SE{}_\K{if}_\N{\$a$\ell$$\ell$user}\V{\_search}\-\!\>\V{code}();}}
\L{\LB{}}
\L{\LB{____\K{print}_\V{OUTPUT}_\S{}\3Found_\3\SE{},_\N{\$a$\ell$$\ell$user}\V{\_search}\-\!\>\V{count}(),}}
\L{\LB{________\S{}\3_entries_(students))_in_VTC_LDAP_server.\2n\3\SE{};}}
\L{\LB{}}
\L{\LB{____\V{bind\_as\_admin\_to\_local\_server}();}}
\L{\LB{}}
\L{\LB{____\V{create\_basic\_groups}();}}
\L{\LB{}}
\L{\LB{____\K{open}_\V{PASSWD\_INFO},_\S{}\3\>_\$passwd\_info\_file\3\SE{}}}
\L{\LB{________\V{or}_\K{die}_\S{}\3cannot_open_\$passwd\_info\_file:_\$!\3\SE{};}}
\L{\LB{____\K{dbmopen}(_\%\V{passwd\_dbm\_hash},_\N{\$passwd}\V{\_dbm\_database},_\N{0600}_)}}
\L{\LB{________\V{or}_\K{die}_\S{}\3Cannot_open_password_database:_\$!\3\SE{};}}
\L{\LB{}}
\L{\LB{____\K{foreach}_\V{my}_\N{\$entry}_(_\N{\$a$\ell$$\ell$user}\V{\_search}\-\!\>\V{all\_entries}()_)}}
\L{\LB{____\{}}
\L{\LB{________\V{my}_\N{\$cn}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4cn\4\SE{}_);}}
\L{\LB{________\K{print}_\V{OUTPUT}_\S{}\3\$cn\2n\3\SE{};}}
\L{\LB{________\V{my}_\N{\$uid}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4uid\4\SE{}_);}}
\L{\LB{}\Tab{8}{\V{my}_\N{\$acOwner}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4acOwner\4\SE{}_);}}
\L{\LB{}\Tab{8}{\V{my}_\N{\$acType}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4acType\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$course}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4course\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$year}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4year\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$mai$\ell$}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4mail\4\SE{}_)_\|\,\|_\S{}\3\$uid\2@stu.vtc.edu.hk\3\SE{};}}
\L{\LB{________\V{my}_\N{\$academicyear}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4academicyear\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$courseduration}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4courseduration\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$registrationdate}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4registrationdate\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$c$\ell$asscode}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4classcode\4\SE{}_);}}
\L{\LB{________\V{my}_\N{\$fina$\ell$year}_=_\N{\$entry}\-\!\>\V{get\_value}(_\S{}\4finalyear\4\SE{}_);}}
\L{\LB{________\N{\$entry}\-\!\>\K{dump}()_\K{if}_\N{\$debug};}}
\L{\LB{}\Tab{8}{\N{\$new}\V{\_entry}_=_\V{Net}::\V{LDAP}::\V{Entry}\-\!\>\V{new};}}
\L{\LB{}\Tab{8}{\N{\$new}\V{\_entry}}}
\L{\LB{________\V{my}_@\V{secondary\_groups}_=_(_\S{}\3students\3\SE{},_\N{\$course},_\S{}\3year\3\SE{}_._\N{\$year}_);}}
\L{\LB{\C{}________\#_Effect_of_next_line_is_to_generate_passwords_on_new_accounts,}}
\CE{}\L{\LB{\C{}________\#_and_to_leave_any_existing_passwords_on_existing_accounts_unchanged.}}
\CE{}\L{\LB{________\V{my}_\N{\$passwd}_=_\S{}\3\3\SE{};}}
\L{\LB{________\V{add\_or\_update\_user}(_\N{\$uid},_\N{\$cn},_\N{\$mai$\ell$},_\N{\$passwd},_@\V{secondary\_groups}_);}}
\L{\LB{}}
\L{\LB{\C{}________\#_(_}}
\CE{}\L{\LB{\C{}________\#__\$uid,_\$cn,_\$course,_\$year,_\$mail,_\$academicyear,}}
\CE{}\L{\LB{\C{}________\#__\$courseduration,_\$registrationdate,_\$classcode,}}
\CE{}\L{\LB{\C{}________\#__\$finalyear}}
\CE{}\L{\LB{\C{}________\#_);}}
\CE{}\L{\LB{____\}}}
\L{\LB{____\K{close}_\V{PASSWD\_INFO};}}
\L{\LB{____\K{dbmclose}_\%\V{passwd\_dbm\_hash};}}
\L{\LB{}}
\L{\LB{\C{}____\#_Probably_unnessary,_but_C_programmers_are_cautious_that_way:}}
\CE{}\L{\LB{____\N{\$$\ell$dap}\V{\_vtc}\-\!\>\V{unbind};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{}}
\L{\LB{\C{}\#_sub_import\_and\_update\_student\_accounts\_from\_vtc\_ldap\_server()}}
\CE{}\L{\LB{\C{}\#_\{}}
\CE{}\L{\LB{\C{}\#_____my_\$ldap\_vtc_=_Net::LDAP-\!\>new(_\3ldap.vtc.edu.hk\3_)_or_die_\3\$@\3;}}
\CE{}\L{\LB{\C{}\#_____my_\$mesg\_vtc_=_\$ldap\_vtc-\!\>bind(_version_=\>_3_);_\#_use_for_searches}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____die_\3Failed_to_bind_to_VTC_ldap_server:_\3,_\$mesg\_vtc-\!\>code(),_\3\2n\3}}
\CE{}\L{\LB{\C{}\#_________if_\$mesg\_vtc-\!\>code();}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____my_\$basedn_=_\3ou=ICT,ou=TY,ou=stu,o=vtc.edu.hk\3;}}
\CE{}\L{\LB{\C{}\#_____my_\$alluser\_search_=_\$ldap\_vtc-\!\>search(}}
\CE{}\L{\LB{\C{}\#____________________________________base_=\>_\$basedn,}}
\CE{}\L{\LB{\C{}\#____________________________________scope_=\>_\3one\3,}}
\CE{}\L{\LB{\C{}\#____________________________________\#_filter_=\>_\3(\|(department=CM)(department=ICT))\3,}}
\CE{}\L{\LB{\C{}\#____________________________________filter_=\>_\3(uid=\*)\3,}}
\CE{}\L{\LB{\C{}\#____________________________________);}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____warn_\3PROBLEM:_Cannot_search_for_all_ICT_studnet_members_in_VTC_LDAP_server:_\3,}}
\CE{}\L{\LB{\C{}\#_______\$alluser\_search-\!\>code(),_\3\2n\3_if_\$alluser\_search-\!\>code();}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____print_OUTPUT_\3Found_\3,_\$alluser\_search-\!\>count(),}}
\CE{}\L{\LB{\C{}\#_________\3_entries_(students)_in_VTC_LDAP_server.\2n\3;}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____bind\_as\_admin\_to\_local\_server();}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____create\_basic\_groups();}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____open_PASSWD\_INFO,_\3\>_\$passwd\_info\_file\3}}
\CE{}\L{\LB{\C{}\#_________or_die_\3cannot_open_\$passwd\_info\_file:_\$!\3;}}
\CE{}\L{\LB{\C{}\#_____dbmopen(_\%passwd\_dbm\_hash,_\$passwd\_dbm\_database,_0600_)}}
\CE{}\L{\LB{\C{}\#_________or_die_\3Cannot_open_password_database:_\$!\3;}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____foreach_my_\$entry_(_\$alluser\_search-\!\>all\_entries()_)}}
\CE{}\L{\LB{\C{}\#_____\{}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3Found_entry:\3;}}
\CE{}\L{\LB{\C{}\#_________my_\$cn_=_\$entry-\!\>get\_value(_\4cn\4_);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3_cn=\2\3\$cn\2\3\2n\3;}}
\CE{}\L{\LB{\C{}\#_________set\_default\_classes(_\$entry,_\4student\4_);}}
\CE{}\L{\LB{\C{}\#_________my_\$uid_=_\$entry-\!\>get\_value(_\4uid\4_);}}
\CE{}\L{\LB{\C{}\#_________my_\$mail_=_\$entry-\!\>get\_value(_\4mail\4_)_\|\,\|_\3\$uid\2@stu.vtc.edu.hk\3;}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\31:_Still_here_with_cn=\2\3\$cn\2\3\2n\3;}}
\CE{}\L{\LB{\C{}\#_________my_@attributes\_to\_delete_=_(}}
\CE{}\L{\LB{\C{}\#_____________________________________\4grpcheckinfo\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4mail\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4maildeliveryoption\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4mailhost\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4mailquota\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4nslicensedfor\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4nsmsgdisallowaccess\4,}}
\CE{}\L{\LB{\C{}\#_____________________________________\4nswmextendeduserprefs\4,}}
\CE{}\L{\LB{\C{}\#____________________________________);}}
\CE{}\L{\LB{\C{}\#_________foreach_my_\$attribute_(_@attributes\_to\_delete_)}}
\CE{}\L{\LB{\C{}\#_________\{}}
\CE{}\L{\LB{\C{}\#_____________if_(_\$entry-\!\>exists(_\$attribute_)_)}}
\CE{}\L{\LB{\C{}\#_____________\{}}
\CE{}\L{\LB{\C{}\#_________________\$entry-\!\>delete(_\$attribute_);}}
\CE{}\L{\LB{\C{}\#_________________print_OUTPUT_\3Deleted_\$attribute_from_\$cn\2n\3;}}
\CE{}\L{\LB{\C{}\#_____________\}}}
\CE{}\L{\LB{\C{}\#_________\}}}
\CE{}\L{\LB{\C{}\#_\#_________\$entry-\!\>delete(}}
\CE{}\L{\LB{\C{}\#_\#________________________\4grpcheckinfo\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4mail\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4maildeliveryoption\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4mailhost\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4mailquota\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4nslicensedfor\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4nsmsgdisallowaccess\4,}}
\CE{}\L{\LB{\C{}\#_\#________________________\4nswmextendeduserprefs\4,}}
\CE{}\L{\LB{\C{}\#_\#_______________________);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\32:_Still_here_with_cn=\2\3\$cn\2\3\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>add(}}
\CE{}\L{\LB{\C{}\#_____________________instituteEmail_=\>_\$mail,}}
\CE{}\L{\LB{\C{}\#_____________________\#_only_f\1t_students_in_vtc_ldap!}}
\CE{}\L{\LB{\C{}\#_____________________fullPartTime___=\>_\4F\4}}
\CE{}\L{\LB{\C{}\#____________________);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\33:_Still_here_with_cn=\2\3\$cn\2\3\2n\3;}}
\CE{}\L{\LB{\C{}\#_________\$entry-\!\>dump;}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\3\$cn\2n\3;}}
\CE{}\L{\LB{\C{}\#_________my_\$course_=_\$entry-\!\>get\_value(_\4course\4_);}}
\CE{}\L{\LB{\C{}\#_________my_\$year_=_\$entry-\!\>get\_value(_\4year\4_);}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_________\$entry-\!\>dump()_if_\$debug;}}
\CE{}\L{\LB{\C{}\#_________my_@secondary\_groups_=_(_\3students\3,_\$course,_\3year\3_._\$year_);}}
\CE{}\L{\LB{\C{}\#_________\#_Effect_of_next_line_is_to_generate_passwords_on_new_accounts,}}
\CE{}\L{\LB{\C{}\#_________\#_and_to_leave_any_existing_passwords_on_existing_accounts_unchanged.}}
\CE{}\L{\LB{\C{}\#_________my_\$passwd_=_\3\3;}}
\CE{}\L{\LB{\C{}\#_________add\_or\_update\_user(_\$entry,_\$passwd,_@secondary\_groups_);}}
\CE{}\L{\LB{\C{}\#_________print_OUTPUT_\35:_Still_here_with_cn=\2\3\$cn\2\3\2n\3;}}
\CE{}\L{\LB{\C{}\#_____\}}}
\CE{}\L{\LB{\C{}\#_____close_PASSWD\_INFO;}}
\CE{}\L{\LB{\C{}\#_____dbmclose_\%passwd\_dbm\_hash;}}
\CE{}\L{\LB{}}
\L{\LB{\C{}\#_____\#_Probably_unnessary,_but_C_programmers_are_cautious_that_way:}}
\CE{}\L{\LB{\C{}\#_____\$ldap\_vtc-\!\>unbind;}}
\CE{}\L{\LB{\C{}\#_\}}}
\CE{}\L{\LB{}}
\L{\LB{\K{sub}_\V{useradd}(\N{\$}\N{\$}\N{\$}\N{\$}@)}}
\L{\LB{\{}}
\L{\LB{____\V{my}_(_\N{\$uid},_\N{\$cn},_\N{\$mai$\ell$},_\N{\$passwd},_@\V{secondary\_groups}_)_=_@\V{\_};}}
\L{\LB{____\V{usage}()_\K{unless}_\N{\$uid};}}
\L{\LB{____\N{\$cn}_=_\N{\$uid}_\K{unless}_\N{\$cn};}}
\L{\LB{____\N{\$mai$\ell$}_=_\S{}\3(unknown)\3\SE{}_\K{unless}_\N{\$mai$\ell$};}}
\L{\LB{____\V{bind\_as\_admin\_to\_local\_server}();}}
\L{\LB{}}
\L{\LB{____\V{create\_basic\_groups}();}}
\L{\LB{____\V{add\_or\_update\_user}(_\N{\$uid},_\N{\$cn},_\N{\$mai$\ell$},_\N{\$passwd},_@\V{secondary\_groups}_);}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{add\_part\_time\_students\_from\_oracle\_text\_files}()}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$course};}}
\L{\LB{____\V{my}_\N{\$year};}}
\L{\LB{____}}
\L{\LB{____\V{bind\_as\_admin\_to\_local\_server}();}}
\L{\LB{____\K{open}_\V{PASSWD\_INFO},_\S{}\3\>_\$passwd\_info\_file\3\SE{}}}
\L{\LB{________\V{or}_\K{die}_\S{}\3cannot_open_\$passwd\_info\_file:_\$!\3\SE{};}}
\L{\LB{____\K{dbmopen}(_\%\V{passwd\_dbm\_hash},_\N{\$passwd}\V{\_dbm\_database},_\N{0600}_)}}
\L{\LB{________\V{or}_\K{die}_\S{}\3Cannot_open_password_database:_\$!\3\SE{};}}
\L{\LB{____\K{while}_(_\<\>_)}}
\L{\LB{____\{}}
\L{\LB{________\V{chomp};}}
\L{\LB{________}}
\L{\LB{________\K{if}_(_\1\5\2\K{s}\*\V{Course}_:\2\K{s}(\2\V{d}+)\2\K{s}\1_)}}
\L{\LB{________\{}}
\L{\LB{____________\N{\$course}_=_\N{\$1};}}
\L{\LB{____________\K{undef}_\N{\$year};}}
\L{\LB{____________\K{next};}}
\L{\LB{________\}}}
\L{\LB{________\K{elsif}_(_\K{m}!\5\2\K{s}\*\V{Course}_:\2\K{s}(\2\V{d}+)\1(\2\V{d})\2\K{s}!_)}}
\L{\LB{________\{}}
\L{\LB{____________\N{\$course}_=_\N{\$1};}}
\L{\LB{____________\N{\$year}_=_\N{\$2};}}
\L{\LB{____________\K{next};}}
\L{\LB{________\}}}
\L{\LB{________\K{if}_(}}
\L{\LB{____________\V{my}_(_\N{\$name},_\N{\$gender},_\N{\$student}\V{\_id},_\N{\$hk}\V{\_id}_)}}
\L{\LB{_________=_\K{m}\{}}
\L{\LB{_________________\2\K{s}\2\K{s}+\C{}______________________\#_at_leaset_2_spaces}}
\CE{}\L{\LB{_________________(\C{}__________________________\#_this_matches_\$name}}
\CE{}\L{\LB{_____________________[\V{A}\-\V{Z}]+\C{}_________________\#_family_name_is_upper_case}}
\CE{}\L{\LB{_____________________(?:\2\K{s}[\V{A}\-\V{Z}][\V{a}\-\V{z}]\*)+\C{}_____\#_one_or_more_given_names}}
\CE{}\L{\LB{_________________)}}
\L{\LB{_________________\2\K{s}\2\K{s}+\C{}______________________\#_at_leaset_2_spaces}}
\CE{}\L{\LB{_________________([\V{MF}])\C{}_____________________\#_gender}}
\CE{}\L{\LB{_________________\2\K{s}+\C{}________________________\#_at_least_one_space}}
\CE{}\L{\LB{_________________(\2\V{d}\{\N{9}\})\C{}____________________\#_student_id_is_9_digits}}
\CE{}\L{\LB{_________________\2\K{s}\2\K{s}+\C{}______________________\#_at_leaset_2_spaces}}
\CE{}\L{\LB{_________________([\V{a}\-\V{zA}\-\V{Z}]\2\V{d}\{\N{6}\}\2([\2\V{dA}\-\V{Z}]\2))\C{}_\#_HK_ID}}
\CE{}\L{\LB{____________\}\V{x}}}
\L{\LB{____________)}}
\L{\LB{________\{}}
\L{\LB{\C{}____________\#_my_\$mail_=_\3\$student\_id\2@stu.vtc.edu.hk\3;}}
\CE{}\L{\LB{____________\V{my}_\N{\$mai$\ell$}_=_\S{}\3(unknown)\3\SE{};}}
\L{\LB{____________\V{my}_\N{\$passwd}_=_\N{\$hk}\V{\_id};}}
\L{\LB{____________\V{my}_@\V{secondary\_groups}_=_(_\S{}\3students\3\SE{},_\N{\$course}_);}}
\L{\LB{____________\K{push}_@\V{secondary\_groups},_\S{}\3year\3\SE{}_._\N{\$year}_\K{if}_\N{\$year};}}
\L{\LB{___________}}
\L{\LB{____________\V{add\_or\_update\_user}(_\N{\$student}\V{\_id},_\N{\$name},_\N{\$mai$\ell$},_\N{\$passwd},}}
\L{\LB{________________________________@\V{secondary\_groups}_);}}
\L{\LB{____________\K{print}_\V{OUTPUT}_\S{}\3sex=\$gender,_student_ID_=_\$student\_id,_\3\SE{},}}
\L{\LB{____________\S{}\3hkID_=_\$hk\_id,_course_=_\$course,_name=\$name,_\3\SE{},}}
\L{\LB{____________\K{defined}_\N{\$year}_?_\S{}\3year_=_\$year\2n\3\SE{}_:_\S{}\3\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____________\K{next};}}
\L{\LB{________\}}}
\L{\LB{________\K{warn}_\S{}\3POSSIBLE_UNMATCHED_STUDENT:_\$\_\2n\3\SE{}_\K{if}_\K{m}!\5\2\K{s}\*\2\V{d}+\2\K{s}+!;}}
\L{\LB{____\}}}
\L{\LB{____\K{close}_\V{PASSWD\_INFO};}}
\L{\LB{____\K{dbmclose}_\%\V{passwd\_dbm\_hash};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{add\_part\_time\_students\_from\_grs\_text\_files}()}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$course};}}
\L{\LB{____\V{my}_\N{\$year};}}
\L{\LB{}}
\L{\LB{____\V{bind\_as\_admin\_to\_local\_server}();}}
\L{\LB{____\K{open}_\V{PASSWD\_INFO},_\S{}\3\>_\$passwd\_info\_file\3\SE{}}}
\L{\LB{________\V{or}_\K{die}_\S{}\3cannot_open_\$passwd\_info\_file:_\$!\3\SE{};}}
\L{\LB{____\K{dbmopen}(_\%\V{passwd\_dbm\_hash},_\N{\$passwd}\V{\_dbm\_database},_\N{0600}_)}}
\L{\LB{________\V{or}_\K{die}_\S{}\3Cannot_open_password_database:_\$!\3\SE{};}}
\L{\LB{____\K{while}_(_\<\>_)}}
\L{\LB{____\{}}
\L{\LB{________\V{chomp};}}
\L{\LB{________\K{if}_(_\K{m}!\5(\2\V{d}+)\1(\2\V{d})\2\K{s}!_)}}
\L{\LB{________\{}}
\L{\LB{____________\N{\$course}_=_\N{\$1};}}
\L{\LB{____________\N{\$year}_=_\N{\$2};}}
\L{\LB{____________\K{next};}}
\L{\LB{________\}}}
\L{\LB{________\K{if}_(}}
\L{\LB{____________\V{my}_(_\N{\$name},_\N{\$gender},_\N{\$student}\V{\_id},_\N{\$hk}\V{\_id}_)}}
\L{\LB{____________=_\K{m}\{}}
\L{\LB{_________________\2\K{s}+\C{}________________________\#_at_leaset_1_space}}
\CE{}\L{\LB{_________________(\C{}__________________________\#_this_matches_\$name}}
\CE{}\L{\LB{_____________________[\V{A}\-\V{Z}]+,?\C{}_______________\#_family_name_is_upper_case_with_comma}}
\CE{}\L{\LB{_____________________(?:\2\K{s}[\V{A}\-\V{Z}][\V{a}\-\V{z}]\*)+\C{}_____\#_one_or_more_given_names}}
\CE{}\L{\LB{_________________)}}
\L{\LB{_________________\2\K{s}\2\K{s}+\C{}______________________\#_at_leaset_2_spaces}}
\CE{}\L{\LB{_________________([\V{MF}])\C{}_____________________\#_gender}}
\CE{}\L{\LB{_________________\2\K{s}+\C{}________________________\#_at_least_one_space}}
\CE{}\L{\LB{_________________(\2\V{d}\{\N{9}\})\C{}____________________\#_student_id_is_9_digits}}
\CE{}\L{\LB{_________________\2\K{s}\2\K{s}+\C{}______________________\#_at_leaset_2_spaces}}
\CE{}\L{\LB{_________________([\V{a}\-\V{zA}\-\V{Z}]\2\V{d}\{\N{6}\}\2([\2\V{dA}\-\V{Z}]\2))\C{}_\#_HK_ID}}
\CE{}\L{\LB{_______________\}\V{x}}}
\L{\LB{____________)}}
\L{\LB{________\{}}
\L{\LB{\C{}____________\#_my_\$mail_=_\3\$student\_id\2@stu.vtc.edu.hk\3;}}
\CE{}\L{\LB{____________\V{my}_\N{\$mai$\ell$}_=_\S{}\3(unknown)\3\SE{};}}
\L{\LB{____________\V{my}_\N{\$passwd}_=_\N{\$hk}\V{\_id};}}
\L{\LB{____________\V{my}_@\V{secondary\_groups}_=_(_\S{}\3students\3\SE{},_\N{\$course}_);}}
\L{\LB{____________\K{push}_@\V{secondary\_groups},_\S{}\3year\3\SE{}_._\N{\$year}_\K{if}_\N{\$year};}}
\L{\LB{___________}}
\L{\LB{____________\V{add\_or\_update\_user}(_\N{\$student}\V{\_id},_\N{\$name},_\N{\$mai$\ell$},_\N{\$passwd},}}
\L{\LB{________________________________@\V{secondary\_groups}_);}}
\L{\LB{____________\K{print}_\V{OUTPUT}_\S{}\3sex=\$gender,_student_ID_=_\$student\_id,_\3\SE{},}}
\L{\LB{____________\S{}\3hkID_=_\$hk\_id,_course_=_\$course,_name=\$name,_\3\SE{},}}
\L{\LB{____________\K{defined}_\N{\$year}_?_\S{}\3year_=_\$year\2n\3\SE{}_:_\S{}\3\2n\3\SE{}_\K{if}_\N{\$debug};}}
\L{\LB{____________\K{next};}}
\L{\LB{________\}}}
\L{\LB{________\K{warn}_\S{}\3POSSIBLE_UNMATCHED_STUDENT:_\$\_\2n\3\SE{}_\K{if}_\K{m}!\5\2\K{s}\*\2\V{d}+\2\K{s}+!;}}
\L{\LB{____\}}}
\L{\LB{____\K{close}_\V{PASSWD\_INFO};}}
\L{\LB{____\K{dbmclose}_\%\V{passwd\_dbm\_hash};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\K{sub}_\V{usage}()}}
\L{\LB{\{}}
\L{\LB{____\V{my}_\N{\$prog}_=_\V{basename}(_\N{\$0}_);}}
\L{\LB{____\K{print}_\V{STDERR}_\<\!\!\<\V{USAGE};}}
\L{\LB{\V{Usage}:\2\V{t}\N{\$prog}_[\V{OPTIONS}]_[\V{oracle}\-\V{or}\-\V{GRS}\-\V{text}\-\V{files}.\,.\,.]}}
\L{\LB{\-\V{d}_\-\-\V{debug}\2\V{tenable}_\V{more}_\V{messages}_\V{about}_\V{what}_\V{is}_\V{happening}}}
\L{\LB{\-\V{a}_\-\-\V{useradd}\2\V{tadd}_\V{a}_\V{single}_\V{user}.__\V{These}_\K{next}_\V{options}_\V{only}_\V{useful}_\K{for}_\V{that}:}}
\L{\LB{\2\V{t}\2\V{t}\-\V{u}_\V{userID}}}
\L{\LB{\2\V{t}\2\V{t}\-\V{c}_\V{users}_\V{full}_\V{name}}}
\L{\LB{\2\V{t}\2\V{t}\-\K{m}_\V{email}_\V{address}}}
\L{\LB{\2\V{t}\2\V{t}\-\V{p}_\V{password}}}
\L{\LB{\2\V{t}\2\V{t}\-\V{g}_\V{group1},\V{group2},.\,.\,.\2\V{tcomma}\-\V{separated}_\V{list}_\V{of}_\V{secondary}_\V{groups}}}
\L{\LB{\-\V{l}_\-\-\V{fromldap}\2\V{t}\2\V{timport}\1\V{update}_\V{user}_\V{accounts}_\V{from}_\V{VTC}_\V{ldap}_\V{server}}}
\L{\LB{\-\-\V{invent}\-\V{passwords}\2\V{tGenerate}_\V{new}_\V{passwords}_\K{for}_\V{all}_\V{existing}_\V{accounts}}}
\L{\LB{\2\V{t}\2\V{t}\2\V{tthat}_\V{are}_\V{tupdated}.__\V{Use}_\V{with}_\V{caution}!!}}
\L{\LB{\-\V{o}_\-\-\V{oracle}\-\V{part}\-\K{time}\2\V{timport}\1\V{update}_\V{part}\-\K{time}_\V{user}_\V{acounts}_\V{from}_\V{Oracle}}}
\L{\LB{\2\V{t}\2\V{t}\2\V{ttext}_\V{files}}}
\L{\LB{\-\V{g}_\-\-\V{grs}\-\V{part}\-\K{time}\2\V{timport}\1\V{update}_\V{part}\-\K{time}_\V{user}_\V{acounts}_\V{from}_\V{grs}_\V{text}_\V{files}}}
\L{\LB{}}
\L{\LB{\V{Should}_\V{be}_\V{able}_\V{to}_\V{be}_\V{run}_\V{many}_\K{times}_\V{as}_\V{VTC}_\V{ldap}_\V{server}_\V{is}_\V{updated}_\V{without}}}
\L{\LB{\V{hurting}_\V{existing}_\V{accounts}.}}
\L{\LB{}}
\L{\LB{\V{Any}_\V{problems}:_\V{Nick}_\V{Urbanik}_\<\V{nicku}\2@\V{vtc}.\V{edu}.\V{hk}\>,_\V{tel}._\N{2436}_\N{8576}}}
\L{\LB{\V{USAGE}}}
\L{\LB{____\K{exit}_\N{0};}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\Proc{main}\K{sub}_\V{main}}}
\L{\LB{\{}}
\L{\LB{\C{}____\#_Getopt::Long::Configure(_\3bundling\3_);}}
\CE{}\L{\LB{____\V{GetOptions}(_\S{}\3useradd!\3\SE{}___=\>_\2\N{\$useradd},}}
\L{\LB{________________\S{}\3a!\3\SE{}_________=\>_\2\N{\$useradd},}}
\L{\LB{________________\S{}\3d:i\3\SE{}________=\>_\2\N{\$debug},}}
\L{\LB{________________\S{}\3debug:i\3\SE{}____=\>_\2\N{\$debug},}}
\L{\LB{________________\S{}\3fromldap!\3\SE{}__=\>_\2\N{\$import}\V{\_vtc\_ldap},}}
\L{\LB{________________\S{}\3l!\3\SE{}_________=\>_\2\N{\$import}\V{\_vtc\_ldap},}}
\L{\LB{________________\S{}\3u=s\3\SE{}________=\>_\2\N{\$uid}\V{\_to\_add},}}
\L{\LB{________________\S{}\3c=s\3\SE{}________=\>_\2\N{\$users}\V{\_full\_name},}}
\L{\LB{________________\S{}\3m=s\3\SE{}________=\>_\2\N{\$emai$\ell$}\V{\_address},}}
\L{\LB{________________\S{}\3g=s\3\SE{}________=\>_\2@\V{other\_groups},}}
\L{\LB{________________\S{}\3p=s\3\SE{}________=\>_\2\N{\$passwd},}}
\L{\LB{\C{}________________\#_\3invent-passwords!\3_=\>_\2\$gen\_new\_password,}}
\CE{}\L{\LB{________________\S{}\3o!\3\SE{}_________=\>_\2\N{\$orac$\ell$e}\V{\_part\_time\_text\_files},}}
\L{\LB{________________\S{}\3g!\3\SE{}_________=\>_\2\N{\$grs}\V{\_part\_time\_text\_files},}}
\L{\LB{________________\S{}\3oracle\-part\-time!\3\SE{}_=\>_\2\N{\$orac$\ell$e}\V{\_part\_time\_text\_files},}}
\L{\LB{________________\S{}\3grs\-part\-time!\3\SE{}____=\>_\2\N{\$grs}\V{\_part\_time\_text\_files},}}
\L{\LB{______________)_\V{or}_\V{usage}();}}
\L{\LB{}}
\L{\LB{____\V{usage}()_\K{unless}_\N{\$useradd}_\V{or}_\N{\$import}\V{\_vtc\_ldap}}}
\L{\LB{________\V{or}_\N{\$orac$\ell$e}\V{\_part\_time\_text\_files}_\V{or}_\N{\$grs}\V{\_part\_time\_text\_files};}}
\L{\LB{\C{}____\#_See_man_Getopt::Long,_search_for_array:}}
\CE{}\L{\LB{____@\V{other\_groups}_=_\K{split}(_\1,\1,_\K{join}(_\S{}\4,\4\SE{},_@\V{other\_groups}_)_);}}
\L{\LB{____\V{slurp\_entire\_dictionary}();}}
\L{\LB{____\V{read\_all\_group\_info\_from\_ict\_server}();}}
\L{\LB{____\N{\$max}\V{\_uid\_number}_=_\V{read\_all\_uid\_numbers\_get\_greatest}();}}
\L{\LB{____\K{if}_(_\N{\$import}\V{\_vtc\_ldap}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{import\_and\_update\_student\_accounts\_from\_vtc\_ldap\_server}();}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_\N{\$useradd}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{useradd}(_\N{\$uid}\V{\_to\_add},_\N{\$users}\V{\_full\_name},}}
\L{\LB{_________________\N{\$emai$\ell$}\V{\_address},_\N{\$passwd},_@\V{other\_groups}_);}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_\N{\$orac$\ell$e}\V{\_part\_time\_text\_files}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{add\_part\_time\_students\_from\_oracle\_text\_files}();}}
\L{\LB{____\}}}
\L{\LB{____\K{elsif}_(_\N{\$grs}\V{\_part\_time\_text\_files}_)}}
\L{\LB{____\{}}
\L{\LB{________\V{add\_part\_time\_students\_from\_grs\_text\_files}();}}
\L{\LB{____\}}}
\L{\LB{____\K{else}}}
\L{\LB{____\{}}
\L{\LB{________\V{usage}();}}
\L{\LB{____\}}}
\L{\LB{____\N{\$$\ell$dap}\V{\_ict}\-\!\>\V{unbind}}}
\L{\LB{\}}}
\L{\LB{}}
\L{\LB{\V{main}();}}
\end{lgrind}
\end{document}
