%% options copyright owner = Dirk Krause copyright year = 2011-2014 license = bsd %% module #include "dk3all.h" #include "dkt.h" #include "dkwt.h" $!trace-include /** Job structure for dkwt accounts. */ typedef struct { dk3_app_t *app; /**< Application structure. */ dkChar const * const *msg; /**< Localized message texts. */ dkChar const * const *kwnl; /**< Keywords, not localized. */ dk3_option_set_t *opt; /**< Options set. */ int f_long; /**< Flag: Long user listing. */ int exval; /**< Exit status code. */ } DKWT_ACC_J; /** Account flag description. */ typedef struct { DWORD dw; /**< Binary flag. */ size_t msgi; /**< Index of description text. */ } DKWT_ACC_FLAG; /** Data for the option set. */ static dk3_option_t const dkwt_accounts_options[] = { { dkT('l'), dkT("long"), 0 }, { dkT('s'), dkT("short"), 0 } }; /** Number of options in the dkt_sort_options array. */ static size_t const dkwt_accounts_szoptions = sizeof(dkwt_accounts_options)/sizeof(dk3_option_t); /** Connection of account flags and text array indices. */ static const DKWT_ACC_FLAG dkwt_accounts_flags[] = { { UF_NORMAL_ACCOUNT, 26 }, { UF_TEMP_DUPLICATE_ACCOUNT, 27 }, { UF_WORKSTATION_TRUST_ACCOUNT, 28 }, { UF_SERVER_TRUST_ACCOUNT, 29 }, { UF_INTERDOMAIN_TRUST_ACCOUNT, 30 }, { UF_TRUSTED_FOR_DELEGATION, 23 }, { UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, 25 }, { UF_ACCOUNTDISABLE, 12 }, { UF_LOCKOUT, 16 }, { UF_PASSWD_NOTREQD, 14 }, { UF_PASSWD_CANT_CHANGE, 15 }, { UF_PASSWORD_EXPIRED, 24 }, { UF_DONT_EXPIRE_PASSWD, 17 }, { UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, 18 }, { UF_NOT_DELEGATED, 19 }, { UF_SMARTCARD_REQUIRED, 20 }, { UF_USE_DES_KEY_ONLY, 21 }, { UF_DONT_REQUIRE_PREAUTH, 22 }, { UF_SCRIPT, 11 }, { UF_HOMEDIR_REQUIRED, 13 }, }; /** Connection of operator account flags and text array indices. */ static const DKWT_ACC_FLAG dkwt_accounts_operator[] = { { AF_OP_ACCOUNTS, 33 }, { AF_OP_SERVER, 34 }, { AF_OP_COMM, 35 }, { AF_OP_PRINT, 36 } }; /** Initialize job structure. @param j Job structure. */ static void dkwt_accounts_job_init(DKWT_ACC_J *j) { j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL; j->f_long = 1; j->exval = DKT_RESULT_ERR_UNSPECIFIC; } /** Clean up job structure after use. @param j Job structure. */ static void dkwt_accounts_job_cleanup(DKWT_ACC_J *j) { if(j->opt) { dk3opt_close(j->opt); } j->opt = NULL; } /** Process command line arguments. @param j Job structure. @return 1 on success, 0 on error. */ static int dkwt_accounts_process_argv(DKWT_ACC_J *j) { int back = 0; int xargc; dkChar const * const *xargv; xargc = dk3app_get_argc(j->app); xargv = dk3app_get_argv(j->app); xargv++; xargv++; xargc--; xargc--; j->opt = dk3opt_open_app( dkwt_accounts_options, dkwt_accounts_szoptions, dkT('\0'), NULL, xargc, xargv, j->app ); if(j->opt) { if(0 == dk3opt_get_error_code(j->opt)) { back = 1; if(dk3opt_is_set(j->opt, dkT('l'))) { j->f_long = 2; if(dk3opt_is_set(j->opt, dkT('s'))) { back = 0; /* ERROR: -l and -s are exclusive. */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 75); } } else { if(dk3opt_is_set(j->opt, dkT('s'))) { j->f_long = 0; } } if(dk3opt_get_num_args(j->opt) > 0) { /* Warning: Arguments ignored. */ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76); } } } return back; } /** Report one detail about an account. @param msg Array containing localized texts. @param imsg Index of attribute name. @param dettxt Description text. */ static void dkwt_ac_detail(dkChar const * const *msg, size_t imsg, dkChar const *dettxt) { dk3sf_fputs(msg[imsg], stdout); dk3sf_fputc(dkT(' '), stdout); dk3sf_fputs(dettxt, stdout); dk3sf_fputc(dkT('\n'), stdout); } /** Report user type for account. @param j Job structure. @param n Index of user type name in message text array. */ static void dkwt_accounts_user_type(DKWT_ACC_J *j, size_t n) { dk3sf_fputs((j->msg)[6], stdout); dk3sf_fputc(dkT(' '), stdout); dk3sf_fputs((j->msg)[n], stdout); dk3sf_fputc(dkT('\n'), stdout); } /** Show flags for an account. @param j Job structure. @param dw Flag set for account. @param jarr Private account flag set. @param sarr Number of inspections. @param itext Index in text array. */ static void dkwt_accounts_show_flags( DKWT_ACC_J *j, DWORD dw, DKWT_ACC_FLAG const *jarr, size_t sarr, size_t itext ) { int is_first = 1; DKWT_ACC_FLAG const *fptr; size_t i; fptr = jarr; for(i = 0; i < sarr; i++) { if((dw) & (fptr->dw)) { dk3sf_fputs((j->msg)[(is_first) ? itext : 10], stdout); dk3sf_fputc(dkT(' '), stdout); dk3sf_fputs((j->msg)[fptr->msgi], stdout); dk3sf_fputc(dkT('\n'), stdout); is_first = 0; } fptr++; } } /** Show a numeric value. @param j Job structure. @param imsg Index in message text array. @param val Value to show. */ static void dkwt_ac_numeric(DKWT_ACC_J *j, size_t imsg, DWORD val) { dkChar b1[64]; dkChar b2[DK3_SIZEOF(b1,dkChar)]; #if VERSION_BEFORE_20140716 dk3sf_sprintf3(b1, dkT("%lu"), (unsigned long)val); dk3sf_sprintf3(b2, dkT("(%lx)"), (unsigned long)val); #else if (0 == dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)val)) { b1[0] = dkT('\0'); } if (0 == dk3ma_um_to_hex_string(b2, DK3_SIZEOF(b2,dkChar),(dk3_um_t)val,0)) { b2[0] = dkT('\0'); } #endif dk3sf_fputs((j->msg)[imsg], stdout); dk3sf_fputc(dkT(' '), stdout); dk3sf_fputs(b1, stdout); dk3sf_fputc(dkT(' '), stdout); dk3sf_fputs(b2, stdout); dk3sf_fputc(dkT('\n'), stdout); } /** Do the accounts listing. @param j Job structure. */ static void dkwt_accounts_run(DKWT_ACC_J *j) { dkwt_account_list_t *al; dkwt_account_t *ac; int found = 0; size_t namelgt; size_t i; al = dkwt_tool_open_account_list(j->app, j->f_long); if(al) { j->exval = DKT_RESULT_OK; dk3sf_initialize_stdout(); dkwt_tool_reset_account_list(al); while((ac = dkwt_tool_get_account_from_list(al)) != NULL) { if((found) && (j->f_long)) { dk3sf_fputc(dkT('\n'), stdout); } found = 1; if(ac->logname) { dk3sf_fputs(ac->logname, stdout); dk3sf_fputc(dkT('\n'), stdout); if(j->f_long) { namelgt = dk3str_len(ac->logname); for(i = 0; i < namelgt; i++) dk3sf_fputc(dkT('-'), stdout); dk3sf_fputc(dkT('\n'), stdout); if(ac->textsid) { dkwt_ac_detail(j->msg, 5, ac->textsid); } if((j->f_long > 1) && (ac->f_long)) { switch(ac->priv) { case USER_PRIV_GUEST: { dkwt_accounts_user_type(j, 7); } break; case USER_PRIV_USER: { dkwt_accounts_user_type(j, 8); } break; case USER_PRIV_ADMIN: { dkwt_accounts_user_type(j, 9); } break; } dkwt_accounts_show_flags( j, ac->flags, dkwt_accounts_flags, sizeof(dkwt_accounts_flags)/sizeof(DKWT_ACC_FLAG), 10 ); dkwt_accounts_show_flags( j, ac->a_flags, dkwt_accounts_operator, sizeof(dkwt_accounts_operator)/sizeof(DKWT_ACC_FLAG), 32 ); } if(ac->fullname) { dkwt_ac_detail(j->msg, 0, ac->fullname); } if(ac->comment) { dkwt_ac_detail(j->msg, 1, ac->comment); } if(ac->usrcomment) { dkwt_ac_detail(j->msg, 2, ac->usrcomment); } if(ac->homedir) { dkwt_ac_detail(j->msg, 3, ac->homedir); } if(ac->profile) { dkwt_ac_detail(j->msg, 4, ac->profile); } if((j->f_long > 1) && (ac->f_long)) { dkwt_ac_numeric(j, 37, ac->coco); dkwt_ac_numeric(j, 38, ac->codepage); } } } } dkwt_tool_close_account_list(al); } } int dkwt_accounts( dk3_app_t *app, dkChar const * const *msg, dkChar const * const *kwnl ) { int back = DKT_RESULT_ERR_UNSPECIFIC; DKWT_ACC_J j; dkwt_accounts_job_init(&j); j.app = app; j.msg = msg; j.kwnl = kwnl; if(dkwt_accounts_process_argv(&j)) { back = j.exval = DKT_RESULT_OK; dkwt_accounts_run(&j); } dkwt_accounts_job_cleanup(&j); return back; }