int parse_command_line(int argc, const char **argv, const char **cl_hostname) { int cl, i; int hn_argc; int sl; int xcmd_len = 0; char *xcmd; int xargc; const char **xargv; Boolean read_session_or_profile = False; /* Figure out who we are */ #if defined(_WIN32) /*[*/ programname = strrchr(argv[0], '\\'); #else /*][*/ programname = strrchr(argv[0], '/'); #endif /*]*/ if (programname) ++programname; else programname = argv[0]; /* Save the command string for tracing purposes. */ cl = strlen(programname); for (i = 0; i < argc; i++) { cl += 1 + strlen(argv[i]); } cl++; command_string = Malloc(cl); (void) strcpy(command_string, programname); for (i = 0; i < argc; i++) { (void) strcat(strcat(command_string, " "), argv[i]); } /* * Save the command-line options so they can be reapplied after * the session file or profile has been read in. */ xcmd_len = 0; for (i = 0; i < argc; i++) xcmd_len += strlen(argv[i]) + 1; xcmd = Malloc(xcmd_len + 1); xargv = (const char **)Malloc((argc + 1) * sizeof(char *)); xcmd_len = 0; for (i = 0; i < argc; i++) { xargv[i] = xcmd + xcmd_len; (void) strcpy(xcmd + xcmd_len, argv[i]); xcmd_len += strlen(argv[i]) + 1; } xargv[i] = CN; *(xcmd + xcmd_len) = '\0'; xargc = argc; #if defined(LOCAL_PROCESS) /*[*/ /* Pick out the -e option. */ parse_local_process(&argc, argv, cl_hostname); #endif /*]*/ /* Set the defaults. */ set_appres_defaults(); /* Parse command-line options. */ parse_options(&argc, argv); /* Pick out the remaining -set and -clear toggle options. */ parse_set_clear(&argc, argv); /* Now figure out if there's a hostname. */ for (hn_argc = 1; hn_argc < argc; hn_argc++) { if (!strcmp(argv[hn_argc], LAST_ARG)) break; } /* Verify command-line syntax. */ switch (hn_argc) { case 1: break; case 2: no_minus(argv[1]); *cl_hostname = argv[1]; break; case 3: no_minus(argv[1]); no_minus(argv[2]); *cl_hostname = xs_buffer("%s:%s", argv[1], argv[2]); break; default: usage("Too many command-line arguments"); break; } /* Delete the host name and any "--". */ if (argv[hn_argc] != CN && !strcmp(argv[hn_argc], LAST_ARG)) hn_argc++; if (hn_argc > 1) { for (i = 1; i < argc - hn_argc + 2; i++) { argv[i] = argv[i + hn_argc - 1]; } } /* Merge in the session. */ if (*cl_hostname != CN && (((sl = strlen(*cl_hostname)) > SESSION_SFX_LEN && !strcasecmp(*cl_hostname + sl - SESSION_SFX_LEN, SESSION_SFX)) #if defined(_WIN32) /*[*/ || ((sl = strlen(*cl_hostname)) > SESSION_SSFX_LEN && !strcasecmp(*cl_hostname + sl - SESSION_SSFX_LEN, SESSION_SSFX)) #endif /*]*/ )) { const char *pname; if (read_resource_file(*cl_hostname, True) < 0) x3270_exit(1); read_session_or_profile = True; pname = strrchr(*cl_hostname, '\\'); if (pname != CN) pname++; else pname = *cl_hostname; profile_name = NewString(pname); Replace(profile_path, NewString(profile_name)); sl = strlen(profile_name); if (sl > SESSION_SFX_LEN && !strcasecmp(profile_name + sl - SESSION_SFX_LEN, SESSION_SFX)) { profile_name[sl - SESSION_SFX_LEN] = '\0'; #if defined(_WIN32) /*[*/ } else if (sl > SESSION_SSFX_LEN && !strcasecmp(profile_name + sl - SESSION_SSFX_LEN, SESSION_SSFX)) { profile_name[sl - SESSION_SSFX_LEN] = '\0'; #endif /*]*/ } *cl_hostname = appres.hostname; /* might be NULL */ } else { /* There is no session file. */ #if defined(C3270) && !defined(_WIN32) /*[*/ /* * For c3270 only, read in the c3270 profile (~/.c3270pro). */ read_session_or_profile = merge_profile(); #endif /*]*/ /* * If there was a hostname resource defined somewhere, but not * as a positional command-line argument, pretend it was one, * so we will connect to it at start-up. */ if (*cl_hostname == CN && appres.hostname != CN) *cl_hostname = appres.hostname; } /* * Now parse the command-line arguments again, so they take * precedence over the session file or profile. */ if (read_session_or_profile) { parse_options(&xargc, xargv); parse_set_clear(&xargc, xargv); } /* Can't free xcmd, parts of it are still in use. */ Free((char *)xargv); /* * All right, we have all of the resources defined. * Sort out the contradictory and implicit settings. */ if (appres.apl_mode) appres.charset = Apl; if (*cl_hostname == CN) appres.once = False; if (appres.conf_dir == CN) appres.conf_dir = LIBX3270DIR; #if defined(X3270_TRACE) /*[*/ if (!appres.debug_tracing) { appres.toggle[TRACING].value = False; } #endif /*]*/ return argc; }
/* Parse the command line and read in any session file. */ int parse_command_line(int argc, const char **argv, const char **cl_hostname) { size_t cl; int i; int hn_argc; size_t sl; size_t xcmd_len = 0; char *xcmd; int xargc; const char **xargv; bool read_session_or_profile = false; /* Figure out who we are */ #if defined(_WIN32) /*[*/ programname = strrchr(argv[0], '\\'); #else /*][*/ programname = strrchr(argv[0], '/'); #endif /*]*/ if (programname) { ++programname; } else { programname = argv[0]; } /* Save the command string for tracing purposes. */ cl = strlen(programname); for (i = 0; i < argc; i++) { cl += 1 + strlen(argv[i]); } cl++; command_string = Malloc(cl); (void) strcpy(command_string, programname); for (i = 0; i < argc; i++) { (void) strcat(strcat(command_string, " "), argv[i]); } /* * Save the command-line options so they can be reapplied after * the session file or profile has been read in. */ xcmd_len = 0; for (i = 0; i < argc; i++) { xcmd_len += strlen(argv[i]) + 1; } xcmd = Malloc(xcmd_len + 1); xargv = (const char **)Malloc((argc + 1) * sizeof(char *)); xcmd_len = 0; for (i = 0; i < argc; i++) { xargv[i] = xcmd + xcmd_len; (void) strcpy(xcmd + xcmd_len, argv[i]); xcmd_len += strlen(argv[i]) + 1; } xargv[i] = NULL; *(xcmd + xcmd_len) = '\0'; xargc = argc; #if defined(LOCAL_PROCESS) /*[*/ /* Pick out the -e option. */ parse_local_process(&argc, argv, cl_hostname); #endif /*]*/ /* Set the defaults. */ set_appres_defaults(); /* Parse command-line options. */ parse_options(&argc, argv); /* Pick out the remaining -set and -clear toggle options. */ parse_set_clear(&argc, argv); /* Now figure out if there's a hostname. */ for (hn_argc = 1; hn_argc < argc; hn_argc++) { if (!strcmp(argv[hn_argc], LAST_ARG)) { break; } } /* Verify command-line syntax. */ switch (hn_argc) { case 1: break; case 2: no_minus(argv[1]); *cl_hostname = argv[1]; break; case 3: no_minus(argv[1]); no_minus(argv[2]); *cl_hostname = xs_buffer("%s:%s", argv[1], argv[2]); break; default: usage("Too many command-line arguments"); break; } /* Delete the host name and any "--". */ if (argv[hn_argc] != NULL && !strcmp(argv[hn_argc], LAST_ARG)) { hn_argc++; } if (hn_argc > 1) { for (i = 1; i < argc - hn_argc + 2; i++) { argv[i] = argv[i + hn_argc - 1]; } } /* Merge in the session. */ if (session_suffix == NULL) { session_suffix = xs_buffer(".%s", app); session_suffix_len = strlen(session_suffix); } #if defined(_WIN32) /*[*/ if (session_short_suffix == NULL) { session_short_suffix = xs_buffer(".%.3s", app); session_short_suffix_len = strlen(session_short_suffix); } #endif /*]*/ if (*cl_hostname != NULL && (((sl = strlen(*cl_hostname)) > session_suffix_len && !strcasecmp(*cl_hostname + sl - session_suffix_len, session_suffix)) #if defined(_WIN32) /*[*/ || ((sl = strlen(*cl_hostname)) > session_short_suffix_len && !strcasecmp(*cl_hostname + sl - session_short_suffix_len, session_short_suffix)) #endif /*]*/ )) { const char *pname; if (!read_resource_file(*cl_hostname, true)) { x3270_exit(1); } read_session_or_profile = true; pname = strrchr(*cl_hostname, '\\'); if (pname != NULL) { pname++; } else { pname = *cl_hostname; } profile_name = NewString(pname); Replace(profile_path, NewString(profile_name)); sl = strlen(profile_name); if (sl > session_suffix_len && !strcasecmp(profile_name + sl - session_suffix_len, session_suffix)) { profile_name[sl - session_suffix_len] = '\0'; #if defined(_WIN32) /*[*/ } else if (sl > session_short_suffix_len && !strcasecmp(profile_name + sl - session_short_suffix_len, session_short_suffix)) { profile_name[sl - session_short_suffix_len] = '\0'; #endif /*]*/ } *cl_hostname = appres.hostname; /* might be NULL */ } else { /* There is no session file. */ /* For c3270 only, read in the c3270 profile (~/.c3270pro). */ if (merge_profilep != NULL) { read_session_or_profile = (*merge_profilep)(); } /* * If there was a hostname resource defined somewhere, but not * as a positional command-line argument, pretend it was one, * so we will connect to it at start-up. */ if (*cl_hostname == NULL && appres.hostname != NULL) { *cl_hostname = appres.hostname; } } /* * Now parse the command-line arguments again, so they take * precedence over the session file or profile. */ if (read_session_or_profile) { parse_options(&xargc, xargv); parse_set_clear(&xargc, xargv); } /* Can't free xcmd, parts of it are still in use. */ Free((char *)xargv); /* * All right, we have all of the resources defined. * Sort out the contradictory and implicit settings. */ if (appres.apl_mode) { appres.charset = Apl; } if (*cl_hostname == NULL) { appres.once = false; } if (!appres.debug_tracing) { /* debug_tracing was explicitly cleared */ set_toggle(TRACING, false); } #if defined(_WIN32) /*[*/ if (appres.utf8) { /* utf8 overrides local_cp */ appres.local_cp = CP_UTF8; } #endif /*]*/ return argc; }