summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* gsm_utils: fix use buf_len instead of sizeof in osmo_dump_gsmtime_bufPhilipp Maier2019-04-081-1/+1
| | | | | | | | | | The function osmo_dump_gsmtime_buf gets a pointer *buf and a parameter buf_len. The pointer *buf is a string buffer and the function places an \0 at the end of the buffer before it exists. However it uses sizeof(buf) as part of the index calculation, which is incorrect. Lets correct this by using buf_len instead. Change-Id: Id24263aa7c9a53544f1639b6ceb09ce5615d5114
* Add _buf() functions to bypass static string buffersHarald Welte2019-04-0325-118/+362
| | | | | | | | | | | | | | | We have a number of static buffers in use in libosmo*. This means the related functions are not usable in a thread-safe way. While we so far don't have many multi-threaded programs in the osmocom universe, the static buffers also prevent us from calling the same e.g. string-ify function twice within a single printf() call. Let's make sure there's an alternative function in all those cases, where the user can pass in a caller-allocated buffer + size, and make the 'classic' function with the static buffer a wrapper around that _buf() variant. Change-Id: Ibf85f79e93244f53b2684ff6f1095c5b41203e05
* osmo_escape_str_buf: Always copy, don't return input string pointerHarald Welte2019-03-294-31/+10
| | | | | | | | | | | osmo_escape_str_buf() used to have the somewhat odd semantics that if no escaping was needed, it would return the original pointer without making any copy to the output buffer. While this seems like an elegant optimization, it is a very strange behavior and it works differently than all of our other *_buf() functions. Let's unify the API and turn osmo_escape_str_buf() into a strlcpy() if no escaping is needed. Change-Id: I3a02bdb27008a73101c2db41ac04248960ed4064
* ipa: Fix ipa_ccm_id_resp_parse on big endian systemsPau Espin Pedrol2019-03-281-2/+2
| | | | Change-Id: Iedc46ab53a4f76bbd98741c065fad3d9042a34a4
* ipa: Document ipa_ccm_idtag_parse_off and fix ipa_ccm_idtag_parsePau Espin Pedrol2019-03-281-1/+11
| | | | | | | | | | | | | | | | | | | | | ipa_ccm_idtag_parse_off is broken, and can only be used with len_offset=1 on ID Request messages, otherwise won't work correctly. Modify ipa_ccm_idtag_parse to at least parse those correctly, and document the limitations. Those two functions are already deprecated and only used in openbsc by 3 callers: * ipa_ccm_idtag_parse in ussd_read_cb(): Broken, that function can only work for Requests and it's used to parse a Response. * ipa_ccm_idtag_parse_off in forward_sccp_to_msc (NAT): Broken, it can only be used to parse Requests and it's used to parse a Response. Furthermore, len_offset=2 is passed which makes no sense and most probably it fails always, or can even make the program crash. * ipa_ccm_idtag_parse_off in (answer_challenge): This one is fine and could actually be replaced with ipa_ccm_id_get_parse after this commit is merged. Change-Id: I6efc852dfc041192f554e41a58290a0f63298021
* src/gsmtap_util.c: fix possible memleak in gsmtap_source_init()Vadim Yanitskiy2019-03-281-0/+1
| | | | | | | In gsmtap_source_init() we dynamically allocate a gsmtap_inst struct, but don't free it if the subsequent call to osmo_fd_register() fails. Change-Id: I970b493f3a64fbe9c3f68fcfba5097ee3ff72960
* BSSGP: use variable for NSEIMax2019-03-281-26/+27
| | | | | | | | Handle NSEI the same way as BVCI is handled: assign it to variable instead of repetitive calls to msgb_nsei() - this simplifies log update in follow-up patches and makes code slightly easier to read. Change-Id: I919a717ca22646849d6ec7f62c677c536db0ed31
* logging_gsmtap.c: document all params of log_target_create_gsmtap()Vadim Yanitskiy2019-03-271-0/+4
| | | | Change-Id: Id7bd6b4fb4be571af351f77aa4a59b9e1076434f
* Doxygen: fix documentation of osmo_timer_setup()Vadim Yanitskiy2019-03-271-2/+2
| | | | | | | | | | | | | | | | | | | | | This change fixes the following Doxygen warnings: timer.c:69: warning: argument 'callback' of command @param is not found in the argument list of osmo_timer_setup(struct osmo_timer_list *timer, void(*cb)(void *data), void *data) timer.c:69: warning: argument 'pointer' of command @param is not found in the argument list of osmo_timer_setup(struct osmo_timer_list *timer, void(*cb)(void *data), void *data) core/timer.h:70: warning: The following parameters of osmo_timer_setup(struct osmo_timer_list *timer, void(*cb)(void *data), void *data) are not documented: parameter 'cb' parameter 'data' Change-Id: If5668f40a7bfde2f4f22329a071c8c6eff23b99e
* src/rate_ctr.c: drop some incorrect \ref referencesVadim Yanitskiy2019-03-271-3/+3
| | | | | | | | | rate_ctr.c:411: warning: unable to resolve reference to `handle_group' for \ref command rate_ctr.c:208: warning: unable to resolve reference to `talloc' for \ref command Change-Id: I24a80ff6cf11ce0455529515d1ecb9900f0271a8
* Doxygen: fix documentation of rate_ctr_for_each_counter()Vadim Yanitskiy2019-03-272-5/+1
| | | | | | | | | | Doxygen was confused by duplicated documentation for both definition and declaration of rate_ctr_for_each_counter(). Moreover, both variants contained some mistakes. Let's avoid this duplication and keep the only (corrected) one. Change-Id: Icca2d4a95bd5f96ae85a86909ec90fb8677cacf3
* core/msgb.h: fix incorrect Doxygen parameter descriptionVadim Yanitskiy2019-03-271-5/+5
| | | | | | | | | | | | | | | | | | | | | core/msgb.h:414: warning: argument 'msgb' of command @param is not found in the argument list of msgb_pull_to_l2(struct msgb *msg) core/msgb.h:399: warning: argument 'msgb' of command @param is not found in the argument list of msgb_pull_to_l3(struct msgb *msg) core/msgb.h:351: warning: argument 'msgb' of command @param is not found in the argument list of msgb_push_u16(struct msgb *msg, uint16_t word) core/msgb.h:361: warning: argument 'msgb' of command @param is not found in the argument list of msgb_push_u32(struct msgb *msg, uint32_t word) core/msgb.h:341: warning: argument 'msgb' of command @param is not found in the argument list of msgb_push_u8(struct msgb *msg, uint8_t word) Change-Id: I5d660933ecfa89c631319eccf9e3d5c1986ec8ff
* src/msgb.c: fix Doxygen documentation for msgb_printf()Vadim Yanitskiy2019-03-271-2/+3
| | | | | | | | | | | | | | | | | This change fixes the following Doxygen warnings: src/msgb.c:479: warning: argument 'msg' of command @param is not found in the argument list of msgb_printf(struct msgb *msgb, const char *format,...) core/msgb.h:708: warning: The following parameters of msgb_printf(struct msgb *msgb, const char *format,...) are not documented: parameter 'msgb' parameter 'format' As a bonus, it dot-terminates all sentences. Change-Id: Ib708664336eef06f748d408ae02a13c754b6647a
* core/msgb.h: drop meaningless parameter of msgb_eq_* helpersVadim Yanitskiy2019-03-271-5/+5
| | | | | | | | | | | | | | | | | | | Thanks to the following Doxygen warning: msgb.h:XXX: warning: The following parameters of msgb_eq_l2(msg1, msgb2, len) are not documented: parameter 'msgb2' parameter 'len' it was discovered that parameter 'len' is not required at all. It basically doesn't make any sense to pass any length value, because it can be calculated using msgb_length(). Let's drop this parameter. Given that this part of the API was broken so far (see I1079d629abdb8770eef6be7341e586a933cd9cca), it should be more or less safe to do this. Change-Id: Icd9b72eb6bfa9628ff1ed2f948b57058551a4328
* core/msgb.h: fix dead msgb2 reference in msgb_eq_* helpersVadim Yanitskiy2019-03-271-5/+5
| | | | | | | | | | | | | | | | | | | | | | Neither Doxygen documentation of the msgb data comparison helpers, nor their actual definitions does refer msgb2. Instead, 'msg2' is referenced in both cases. This was discovered while investigating the following Doxygen warnings: msgb.h:XXX: warning: argument 'msg2' of command @param is not found in the argument list of msgb_eq(msg1, msgb2, len) msgb.h:XXX: warning: The following parameters of msgb_eq_l2(msg1, msgb2, len) are not documented: parameter 'msgb2' parameter 'len' Due to this bug it was impossible to use the affected macros, because 'msg2' was not listed in their parameters. Having the unit test coverage would spot this bug at the beginning! Change-Id: I1079d629abdb8770eef6be7341e586a933cd9cca
* src/logging.c: fix syntax errors in Doxygen documentationVadim Yanitskiy2019-03-271-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change should fix the following warnings: logging.c:956: warning: unable to resolve reference to `talloc' for \ref command logging.c:203: warning: argument 'in' of command @param is not found in the argument list of log_level_str(unsigned int lvl) logging.c:194: warning: argument 'in' of command @param is not found in the argument list of log_parse_level(const char *lvl) logging.c:708: warning: argument 'print_catname' of command @param is not found in the argument list of log_set_print_category(struct log_target *target, int print_category) logging.c:687: warning: argument 'print_filename' of command @param is not found in the argument list of log_set_print_filename2(struct log_target *target, enum log_filename_type lft) logging.c:729: warning: argument 'print_catname' of command @param is not found in the argument list of log_set_print_level(struct log_target *target, int print_level) logging.c:893: warning: argument 'in' of command @param is not found in the argument list of log_target_destroy(struct log_target *target) Change-Id: I85f6c70216b7574b49b90bb1469869a47f721713
* core/linuxlist.h: fix white-space and inconsistent alignmentVadim Yanitskiy2019-03-271-19/+19
| | | | | | | | - fix trailing white-space; - properly align parameters of functions; - use tabs instead of 8 spaces where possible. Change-Id: Iaf616592a6bd72a1e7e94d8c55475710868beef0
* core/linuxlist.h: fix and unify Doxygen documentationVadim Yanitskiy2019-03-271-99/+96
| | | | | | | | | | | - drop incorrect \ref and \a references; - add missing documentation to LLIST_HEAD_INIT; - document parameter 'member' of llist_entry(); - turn @argument naming into a valid \param format; - fix 'type *' vs llist_head loop counter confusion; - capitalize and dot-terminate all sentences. Change-Id: Iac67bdb9d5fbf7c222d04858967337f2428d6a94
* gsm_utils.h: remove unused include of gsm_08_08.hNeels Hofmeyr2019-03-271-1/+0
| | | | Change-Id: Ied4cb2bd06147785540a53ef118e9268406da702
* Revert "ipa_ccm_idtag_parse*: Fix reported length value"Oliver Smith2019-03-251-1/+1
| | | | | | | | | | | | This reverts commit 1261db15058cfa94615f26c1083bb8a38d09218b. The patch broke openbsc's external tests, and currently it is unclear whether it is just an error in the test or if openbsc makes wrong assumptions about the length value. Let's revert the patch to unblock the master-openbsc jenkins job. Related: OS#3851 Change-Id: I9adea35ff6de36c1611c7f85dde1b15bc1c0e786
* Doxygen: fix incorrect / missing parameter descriptionVadim Yanitskiy2019-03-252-4/+4
| | | | Change-Id: Ibc63a5d4442a192efab8b5b30e0beb3545642ecc
* Revert "signal.c: Make non-exported tall_sigh_ctx static"Oliver Smith2019-03-221-1/+1
| | | | | | | | | | | | | This reverts commit cff2242e686be9ac19ba5757a710bc769a9201ec. The patch broke openbsc: ../../src/libcommon/libcommon.a(talloc_ctx.o): In function `talloc_ctx_init': /build/openbsc/src/libcommon/talloc_ctx.c:50: undefined reference to `tall_sigh_ctx' See also: https://lists.osmocom.org/pipermail/openbsc/2019-March/012843.html Change-Id: Ib4cb31427a1cad063bc9f1a10b9c3182b314a9f2
* signal.c: Make non-exported tall_sigh_ctx staticHarald Welte2019-03-211-1/+1
| | | | | | | | | As indicated in the commitlog of Id58ca18eb826b8f4183a7cf0dbb2b38cba702a09, the symbol was never exported in a header file, so it should be safe to mark it as static. Change-Id: I7132ffe9a7efcab226cc639d1b2357f7115bcadf
* signal.c: Fix osmo_signal_talloc_ctx_init()Harald Welte2019-03-211-1/+1
| | | | | | | | | | | | | This function is broken ever since it was added back in 2018 in commit Id58ca18eb826b8f4183a7cf0dbb2b38cba702a09 Rather than allocating from the user-supplied 'root_ctx', it is allocating from the context that it's trying to create (which is NULL at that time, rendering the entire operation more or less a no-op. For sure you will not see osmo_signal structures never in any talloc report. Change-Id: I922d26815a3baa5be74bd3ee89d498555882d62f
* select: Rename BSC_FD_* constants to OSMO_FD_*Harald Welte2019-03-219-37/+42
| | | | | | | | | | | | The naming of these constants dates back to when the code was private within OpenBSC. Everything else was renamed (bsc_fd -> osmo_fd) at the time, but somehow the BSC_FD_* defines have been missed at the time. Keep compatibility #defines around, but allow us to migrate the applications to a less confusing naming meanwhile. Change-Id: Ifae33ed61a7cf0ae54ad487399e7dd2489986436
* src/signal.c: cosmetic: use talloc_zero()Vadim Yanitskiy2019-03-201-3/+1
| | | | Change-Id: I55c6249b0c4c82d5a181001e945ff2eca6e9ca36
* gprs_ns_sns: Properly initialize sockaddr_in in gprs_nsvc_create_ip4()Harald Welte2019-03-201-0/+2
| | | | | | | | When putting together a sockaddr_in, we must not only set the IP address and port, but also set the address family to AF_INET. And while at it, let's zero-initialize the entire 'struct sockdadr_in'. Change-Id: I1c8d8fe7f79a2ec737baa7800247269c3271983e
* socket: osmo_sock_get_name() Use "const void *" as talloc contextHarald Welte2019-03-192-2/+2
| | | | Change-Id: Ie6877277cddb0a9e049449c260afe3314ba65050
* vty/tdef_vty.c: drop redundant comparisonVadim Yanitskiy2019-03-191-1/+1
| | | | | | | | | | | | | | | The amount of arguments is already being checked a few lines before: /* If any arguments are missing, redirect to 'show' */ if (argc < 3) return show_timer(self, vty, argc, argv); so we cannot reach the expression NULL inside this statement: group_arg = argc > 0 ? argv[0] : NULL; Change-Id: Ice59d1a46c2080cd02060e3410706c502db4ce0b Fixes: CID#190873 Logically dead code (DEADCODE)
* ipa_ccm_idtag_parse*: Fix reported length valueHarald Welte2019-03-191-1/+1
| | | | | | | | | | | | | | | IPA CCM is using a somewhat weird TLV encoding scheme: * 16bit length (of tag and value) * 8bit tag * value Our existing code mapping the CCM to 'struct tlv_parse' used the plain length value without accounting for the one-byte tag. This patch ensures we only report the length of the "value" part, excluding the tag. Change-Id: I435aaa33605bd48635715a2c81aa2d231c1abf51
* rate_ctr_group_free(): guard against empty or NULL inputMax2019-03-191-1/+5
| | | | Change-Id: I859a91ee4400b3685c05971f8c66bceca6758724
* tests: use -no-install libtool flag to avoid ./lt-* scriptsHarald Welte2019-03-191-1/+1
| | | | | | | | | This ensures that the rpath of the generated binaries is set to use only the just-compiled libosmo{core,gsm,vty}.so and not any system-wide installed libraries while avoiding the ugly shell script wrapper. Change-Id: I9b9ae0ed277ba71519661a66a70b7f86971e4511
* gprs_ns_sns: Use "correct" remote IP address for local IP endpointHarald Welte2019-03-161-2/+2
| | | | | | | | | | | we cannot use "nsi->nsip.remote_ip", as this address is not set when SNS is in use. We can only have a valid nsi->nsip.remote_ip if there's only a single NS-VC inside the NS Instance, as this would connect() the UDP socket to the remote IP/port, breaking any possibility to have multiple NS-VCs to different SGNS-side IP addresses. Closes: OS#3845 Change-Id: Ic094621eb01d7458063f531289d5eeadf52bf330
* gprs_ns: Don't use initial IP/port for anything but SNSHarald Welte2019-03-161-2/+55
| | | | | | | | | | | | | | | | | | | | | | | Section 6.2.1 of 3GPP TS 48.016 states: > A pre-configured endpoint shall not be used for NSE data or signalling > traffic (with the exception of Size and Configuration procedures) unless > it is configured by the SGSN using the auto-configuration procedures. However, in the current SNS implementation, the initial IP/Port over which we perform the SNS-SIZE + SNS-CONFIG are treated as one of the normal NS-VCs. Specifically, we also perform the NS-ALIVE procedure on it, which is clearly wrong. Let's explicitly create the "initial" NS-VC with data and signalling weight of 0, and ensure we never start the alive timer or send any non-SNS PDUs on this connection as long as SNS was not used to change either of the two weights to non-zero. While at it, also safeguard against processing any incoming non-SNS messages on such a all-zero-weight connection. Change-Id: I16a91a07e5914d123b2ea2f8413b94e7cd518628 Closes: OS#3844
* gprs_ns.c: Update comment: IP SNS has recently been implementedHarald Welte2019-03-161-1/+0
| | | | Change-Id: I8b98621a582a23d0483a5340b4aca7e0bc096e6d
* osmo_gsm48_classmark_a5_name(): fix 'no-cm3' labelNeels Hofmeyr2019-03-141-1/+1
| | | | Change-Id: Id84021858dfb2f7d6a7cf81ae73bd94cd47f6776
* Fix build on non-glibc systemsKarl Koscher2019-03-111-3/+8
| | | | Change-Id: Id5d577522a4889e152158f7e93ee1c99d3a21003
* gsm0808_utils: fix gsm48 multirate to S-bit converterPhilipp Maier2019-03-113-19/+78
| | | | | | | | | | | | The function gsm0808_sc_cfg_from_gsm48_mr_cfg() is used to convert a gsm48 multirate struct into a set of S-bits (S0 to S15). However, the conversion function currently does not take into account that bit S1 actually stands for four rates at once (Config-NB-Code = 1). Lets make sure that S1 is only set when the multirate configuration permits all four required rates. Change-Id: I6ad531d4e70c2252e32e2bbaca8e14a7ec6d9840 Related: SYS#4470
* gsm0808_utils: fix gsm48 multirate configuration generatorPhilipp Maier2019-03-115-57/+313
| | | | | | | | | | | | | | | | | The function gsm0808_sc_cfg_from_gsm48_mr_cfg() takes an S15 to S0 bitmask and converts that bitmask into an AMR multirate configuration struct. Unfortunately the current implementation implements 3GPP TS 28.062, Table 7.11.3.1.3-2 wrongly in some aspects. Lets fix this. - Fix wrong interpretation of the bitpatterns - 5,15K is invalid and must never be selected - Make sure that no more than 4 rates are selected in the active set - Extend unit-test Change-Id: I6fd7f4073b84093742c322752f2fd878d1071e15 Related: SYS#4470
* add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()Neels Hofmeyr2019-03-086-8/+270
| | | | | | | | | | | | | | | | CGI to Cell ID: for example, for Paging, osmo-msc has a CGI for a subscriber and needs to send out a Cell Identifier IE. Makes sense to add this conversion here. Cell ID to CGI: for a Layer 3 Complete, a subscriber sends the current cell in the form of a Cell Identifier, which we store as a CGI, if necessary enriched with the local PLMN. Add enum with bitmask values to identify parts of a CGI, for the return value of gsm0808_cell_id_to_cgi(). Can't use enum CELL_IDENT for that, because it doesn't have a value for just a PLMN (and is not a bitmask). Change-Id: Ib9af67b100c4583342a2103669732dab2e577b04
* fsm: add osmo_fsm_inst_state_chg_keep_or_start_timer()Neels Hofmeyr2019-03-075-17/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | During FSM design for osmo-msc, I noticed that the current behavior that keep_timer=true doesn't guarantee a running timer can make FSM design a bit complex, especially when using osmo_tdef for timeout definitions. A desirable keep_timer=true behavior is one that keeps the previous timer running, but starts a timer if no timer is running yet. The simplest example is: a given state repeatedly transitions back to itself, but wants to set a timeout only on first entering, avoiding to restart the timeout on re-entering. Another example is a repeated transition between two or more states, where the first time we enter this group a timeout should start, but it should not restart from scratch on every transition. When using osmo_tdef timeout definitions for this, so far separate meaningless states have to be introduced that merely set a fixed timeout. To simplify, add osmo_fsm_inst_state_chg_keep_or_start_timer(), and use this in osmo_tdef_fsm_inst_state_chg() when both keep_timer == true *and* T != 0. In tdef_test.ok, the changes show that on first entering state L, the previous T=1 is now kept with a large remaining timeout. When entering state L from O, where no timer was running, this time L's T123 is started. Change-Id: Id647511a4b18e0c4de0e66fb1f35dc9adb9177db
* fix tdef_test.c: do call the function-to-test in all casesNeels Hofmeyr2019-03-063-19/+19
| | | | | | | | | | | | Always call osmo_tdef_fsm_inst_state_chg(), also when no timeout is defined. When there is no timeout defined for a state, tdef_test.c tries to be smart and print different output. In that mess, I missed the fact that osmo_tdef_fsm_inst_state_chg() isn't always called as it should. In the same mess, the resulting state was never printed until the preceding patch, which helped to hide this bug. Change-Id: I1d953d99854422bff8eb32f051e9c6147bc836b6
* tdef_test: tweak output to prepare for a fixNeels Hofmeyr2019-03-063-21/+24
| | | | | | | | | | | | | | - Always print the state after a state transition. This shows that actually state transitions are missing for states that have no timer defined. This is a bug in tdef_test.c, to be fixed subsequently. - Instead of total time passed since start, print the individual fake time intervals. Omit initial useless zero fake time advance. - Add two more state transitions, back out from and into a state that has no timeout set. Change-Id: Icb31af96d37741e256ff07868f3d4f5c48cdda74
* represent negative T-timers as Osmocom-specific X-timersNeels Hofmeyr2019-03-067-52/+111
| | | | | | | | | | | | | | | | | | | | fi->T values are int, i.e. can be negative. Do not log them as unsigned, but define a distinct timer class "Xnnnn" for negative T values: i.e. for T == -1, print "Timeout of X1" instead of "Timeout of T4294967295". The negative T timer number space is useful to distinguish freely invented timers from proper 3GPP defined T numbers. So far I was using numbers like T993210 or T9999 for invented T, but X1, X2 etc. is a better solution. This way we can make sure to not accidentally define an invented timer number that actually collides with a proper 3GPP specified timer number that the author was not aware of at the time of writing. Add OSMO_T_FMT and OSMO_T_FMT_ARGS() macros as standardized timer number print format. Use that in fsm.c, tdef_vty.c, and adjust vty tests accordingly. Mention the two timer classes in various API docs and VTY online-docs. Change-Id: I3a59457623da9309fbbda235fe18fadd1636bff6
* api doc: tweak gsm0808_cell_id_matches_list() docNeels Hofmeyr2019-03-051-1/+2
| | | | Change-Id: Ide94558d1c31356483252b83e04b061b4ee4d3bf
* coding: check gsm0503_rach_*() resultsMax2019-03-051-8/+10
| | | | | | | | Check return value of RACH encode/decode functions and fail test on unexpected results. Change-Id: I41bfa808e3c064a11152e7ce8ee77a01d38a0744 Related: OS#1854
* fix api doc typo for osmo_plmn_name2()Neels Hofmeyr2019-02-261-1/+1
| | | | Change-Id: Ic2652c7e4ffe1e707022168ac6c0da7c88ae7f45
* log: fsm: allow logging the timeout on state changeNeels Hofmeyr2019-02-264-12/+53
| | | | | | | | | | | | | | | | Add a flag that adds timeout info to osmo_fsm_inst state change logging. To not affect unit testing, make this an opt-in feature that is disabled by default -- mostly because osmo_fsm_inst_state_chg_keep_timer() will produce non-deterministic logging depending on timing (logs remaining time). Unit tests that don't verify log output and those that use fake time may also enable this feature. Do so in fsm_test.c. The idea is that in due course we will add osmo_fsm_log_timeouts(true) calls to all of our production applications' main() initializa