/* cvsymbol - convert a string to a symbol */ LVAL cvsymbol(char *pname) { LVAL val; xlsave1(val); val = newvector(SYMSIZE); val->n_type = SYMBOL; setvalue(val,s_unbound); setfunction(val,s_unbound); setpname(val,cvstring(pname)); xlpop(); return (val); }
int main(int argc, char *argv[]) { int c; size_t i; Buffer *buf; errno = 0; setpname(argv[0]); if (argc < 2) die(2, "usage: %s file", getpname()); if ((c = open(argv[1], O_RDONLY)) == -1) die(1, "failed to open file %s:", argv[1]); if ((buf = makebuf(512)) == NULL) die(1, "allocating buffer failed:"); if (initbuf(buf, c, O_RDONLY) == EOF) die(1, "initializing buffer failed:"); i = 0; while ((c = bgetchar(buf)) != EOF) { if (i == 511 || i == 512 || i == 513) { if (bungetchar(buf) == EOF) { die(1, "bungetchar failed at char %lu", i); break; } if ((c = bgetchar(buf)) == EOF) break; } putc(c, stdout); i++; } if (errno != 0) die(1, "bgetchar failed at char %lu:", i); fprintf(stderr, "reached end of input file %s\n", argv[1]); fprintf(stderr, "%lu bytes read\n", i); bclose(buf); exit(0); }
int main(int argc, char *argv[]) { Symtab *symtab; Symbol *sym; setpname(argv[0]); if (argc > 1) fprintf(stderr, "%s: unused arguments\n", getpname()); if ((symtab = makesymtab(0)) == NULL) die(1, "failed to allocate symbol table:"); if ((sym = storesym(symtab, "foo")) == NULL) die(1, "failed to insert lexem \"foo\":"); sym->symtype = S_IDENT; if ((sym = storesym(symtab, "bar")) == NULL) die(1, "failed to insert lexem \"bar\":"); sym->symtype = S_IDENT; if ((sym = storesym(symtab, "baz")) == NULL) die(1, "failed to insert lexem \"baz\":"); sym->symtype = S_IDENT; if ((sym = findsym(symtab, "foo")) == NULL) die(1, "couldn't find lexem \"foo\":"); if (sym->symtype != S_IDENT) die(1, "symtype of \"foo\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "bar")) == NULL) die(1, "couldn't find lexem \"bar\":"); if (sym->symtype != S_IDENT) die(1, "%s: symtype of \"bar\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "baz")) == NULL) die(1, "couldn't find lexem \"baz\":"); if (sym->symtype != S_IDENT) die(1, "symtype of \"baz\" is not S_IDENT"); sym->symtype = S_INTCONST; if ((sym = findsym(symtab, "foo")) == NULL) die(1, "couldn't find lexem \"foo\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"foo\" is not S_INTCONST"); if ((sym = findsym(symtab, "bar")) == NULL) die(1, "couldn't find lexem \"bar\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"bar\" is not S_INTCONST"); if ((sym = findsym(symtab, "baz")) == NULL) die(1, "couldn't find lexem \"baz\":"); if (sym->symtype != S_INTCONST) die(1, "symtype of \"baz\" is not S_INTCONST"); freesymtab(symtab); return 0; }
int main(int argc, char *argv[]) { long pagesize, npages; int c, ret; char hw_provider[SYS_NMLN]; setpname(argv[0]); opts.o_promdev = "/dev/openprom"; while ((c = getopt(argc, argv, optstring)) != -1) { switch (c) { case 'a': ++opts.o_ancestors; break; case 'b': ++opts.o_productinfo; break; case 'c': ++opts.o_children; break; case 'd': ++opts.o_pciid; break; case 'D': ++opts.o_drv_name; break; case 'v': ++opts.o_verbose; break; case 'm': ++opts.o_memory; break; case 'p': ++opts.o_prominfo; break; case 'f': opts.o_promdev = optarg; break; case 'V': ++opts.o_promversion; break; case 'x': ++opts.o_prom_ready64; break; case 'F': ++opts.o_fbname; ++opts.o_noheader; break; case 'P': ++opts.o_pseudodevs; break; case 'C': ++opts.o_forcecache; break; #ifdef DEBUG case 'M': dbg.d_drivername = optarg; ++dbg.d_bydriver; break; case 'L': ++dbg.d_forceload; break; #endif /* DEBUG */ default: (void) fprintf(stderr, usage, opts.o_progname); return (1); } } (void) uname(&opts.o_uts); if (opts.o_fbname) return (do_fbname()); if (opts.o_promversion) return (do_promversion()); if (opts.o_prom_ready64) return (do_prom_version64()); if (opts.o_productinfo) return (do_productinfo()); opts.o_devices_path = NULL; opts.o_devt = DDI_DEV_T_NONE; opts.o_target = 0; if (optind < argc) { struct stat sinfo; char *path = argv[optind]; int error; if (opts.o_prominfo) { /* PROM tree cannot be used with path */ (void) fprintf(stderr, "%s: path and -p option are " "mutually exclusive\n", opts.o_progname); return (1); } if (strlen(path) >= MAXPATHLEN) { (void) fprintf(stderr, "%s: " "path specified is too long\n", opts.o_progname); return (1); } if (error = stat(path, &sinfo)) { /* an invalid path was specified */ (void) fprintf(stderr, "%s: invalid path specified\n", opts.o_progname); return (1); } else if (((sinfo.st_mode & S_IFMT) == S_IFCHR) || ((sinfo.st_mode & S_IFMT) == S_IFBLK)) { opts.o_devt = sinfo.st_rdev; error = 0; } else if ((sinfo.st_mode & S_IFMT) == S_IFDIR) { size_t len, plen; /* clean up the path */ cleanup_path(path, new_path); len = strlen(new_path); plen = strlen("/devices"); if (len < plen) { /* This is not a valid /devices path */ error = 1; } else if ((len == plen) && (strcmp(new_path, "/devices") == 0)) { /* /devices is the root nexus */ opts.o_devices_path = "/"; error = 0; } else if (strncmp(new_path, "/devices/", plen + 1)) { /* This is not a valid /devices path */ error = 1; } else { /* a /devices/ path was specified */ opts.o_devices_path = new_path + plen; error = 0; } } else { /* an invalid device path was specified */ error = 1; } if (error) { (void) fprintf(stderr, "%s: " "invalid device path specified\n", opts.o_progname); return (1); } opts.o_target = 1; } if ((opts.o_ancestors || opts.o_children) && (!opts.o_target)) { (void) fprintf(stderr, "%s: options require a device path\n", opts.o_progname); return (1); } if (opts.o_target) { prtconf_devinfo(); return (0); } if (!opts.o_memory) { ret = sysinfo(SI_HW_PROVIDER, hw_provider, sizeof (hw_provider)); /* * If 0 bytes are returned (the system returns '1', for the \0), * we're probably on x86, and there has been no si-hw-provider * set in /etc/bootrc, default to Joyent. */ if (ret <= 1) { (void) strncpy(hw_provider, "Joyent", sizeof (hw_provider)); } (void) printf("System Configuration: %s %s\n", hw_provider, opts.o_uts.machine); } pagesize = sysconf(_SC_PAGESIZE); npages = sysconf(_SC_PHYS_PAGES); if (pagesize == -1 || npages == -1) if (opts.o_memory) { (void) printf("0\n"); return (1); } else { (void) printf("Memory size: unable to determine\n"); } else { const int64_t kbyte = 1024; const int64_t mbyte = 1024 * 1024; int64_t ii = (int64_t)pagesize * npages; if (opts.o_memory) { (void) printf("%ld\n", (long)((ii+mbyte-1) / mbyte)); return (0); } else { (void) printf("Memory size: %ld Megabytes\n", (long)((ii+mbyte-1) / mbyte)); } } if (opts.o_prominfo) { (void) printf("System Peripherals (PROM Nodes):\n\n"); if (do_prominfo() == 0) return (0); (void) fprintf(stderr, "%s: Defaulting to non-PROM mode...\n", opts.o_progname); } (void) printf("System Peripherals (Software Nodes):\n\n"); (void) prtconf_devinfo(); return (0); }
int main(int argc, char *argv[]) { int interval = 5; int count; int always = 1; int opt; int projects = 0; int zones = 0; /* project reporting is the default if no option is specified */ rcid_type_t stat_type = RCIDT_PROJECT; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); (void) setpname("rcapstat"); global = unformatted = 0; while ((opt = getopt(argc, argv, "gpuzT:")) != (int)EOF) { switch (opt) { case 'g': global = 1; break; case 'p': projects = 1; stat_type = RCIDT_PROJECT; break; case 'u': unformatted = 1; break; case 'z': stat_type = RCIDT_ZONE; zones = 1; break; case 'T': if (optarg) { if (*optarg == 'u') timestamp_fmt = UDATE; else if (*optarg == 'd') timestamp_fmt = DDATE; else usage(); } else { usage(); } break; default: usage(); } } if (argc > optind) if ((interval = xatoi(argv[optind++])) <= 0) die(gettext("invalid interval specified\n")); if (argc > optind) { if ((count = xatoi(argv[optind++])) <= 0) die(gettext("invalid count specified\n")); always = 0; } if (argc > optind || (projects > 0 && zones > 0)) usage(); while (always || count-- > 0) { if (read_stats(stat_type) != E_SUCCESS) return (E_ERROR); if (timestamp_fmt != NODATE) print_timestamp(timestamp_fmt); if (!unformatted) { print_stats(stat_type); (void) fflush(stdout); if (count || always) (void) sleep(interval); } else { struct stat st; print_unformatted_stats(); (void) fflush(stdout); while (stat(STAT_FILE_DEFAULT, &st) == 0 && st.st_mtime == stat_mod) (void) usleep((useconds_t)(0.2 * MICROSEC)); } } return (E_SUCCESS); }
int main(int argc, char *argv[]) { int c; /* options character */ int type = 0; /* type of accounting */ int modified = 0; /* have we modified any properties? */ acctconf_t ac; /* current configuration */ char *typestr = NULL; /* type of accounting argument string */ char *enabled = NULL; /* enabled resources string */ char *disabled = NULL; /* disabled resources string */ char *file = NULL; int Eflg = 0; int Dflg = 0; int rflg = 0; int sflg = 0; int xflg = 0; int optcnt = 0; int state; const char *fmri; /* FMRI for this instance */ int err = 0; setup_privs(); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); (void) setpname(argv[0]); for (; optind < argc; optind++) { while ((c = getopt(argc, argv, OPTS)) != (int)EOF) { switch (c) { case 'd': disabled = optarg; break; case 'e': enabled = optarg; break; case 'D': Dflg = 1; optcnt++; break; case 'E': Eflg = 1; optcnt++; break; case 'f': file = optarg; optcnt++; break; case 'r': rflg = 1; optcnt++; break; case 's': sflg = 1; optcnt++; break; case 'x': xflg = 1; optcnt++; break; case '?': default: usage(); } } /* * Permanently give up euid 0, egid 0 and privileges we * don't need for the specified options. */ if (!(file || sflg)) { if (setreuid(getuid(), getuid()) == -1 || setregid(getgid(), getgid()) == -1) die(gettext("setreuid()/setregid() failed")); (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_FILE_DAC_WRITE, NULL); } if (!(disabled || enabled || Dflg || Eflg || file || sflg || xflg)) (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL); if (optind < argc) { if (typestr != NULL) { warn(gettext("illegal argument -- %s\n"), argv[optind]); usage(); } else { typestr = argv[optind]; } } } if (typestr != NULL) { if (strcmp(typestr, "process") == 0 || strcmp(typestr, "proc") == 0) type |= AC_PROC; else if (strcmp(typestr, "task") == 0) type |= AC_TASK; else if (strcmp(typestr, "flow") == 0) type |= AC_FLOW; else if (strcmp(typestr, "net") == 0) type |= AC_NET; else { warn(gettext("unknown accounting type -- %s\n"), typestr); usage(); } } else type = AC_PROC | AC_TASK | AC_FLOW | AC_NET; /* * Drop the DL config privilege if we are not working with * net. */ if ((type & AC_NET) == 0) { (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_DL_CONFIG, NULL); } /* * check for invalid options */ if (optcnt > 1) usage(); /* * XXX For AC_NET, enabled/disabled should only be "basic" or * "extended" - need to check it here. */ if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg)) usage(); if ((file || xflg || Dflg || Eflg || enabled || disabled) && !typestr) { warn(gettext("accounting type must be specified\n")); usage(); } if (rflg) { printgroups(type); return (E_SUCCESS); } /* * If no arguments have been passed then just print out the current * state and exit. */ if (!enabled && !disabled && !file && !Eflg && !rflg && !Dflg && !sflg && !xflg) { aconf_print(stdout, type); return (E_SUCCESS); } /* Open the libdladm handle */ if (dladm_open(&dld_handle) != DLADM_STATUS_OK) die(gettext("failed to open dladm handle\n")); /* * smf(5) start method. The FMRI to operate on is retrieved from the * SMF_FMRI environment variable that the restarter provides. */ if (sflg) { if ((fmri = getenv("SMF_FMRI")) != NULL) { int ret = aconf_setup(fmri); dladm_close(dld_handle); return (ret); } die(gettext("-s option should only be invoked by smf(5)\n")); } assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW || type == AC_NET); if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID) die(gettext("%s accounting cannot be configured in " "non-global zones\n"), ac_type_name(type)); fmri = aconf_type2fmri(type); if (aconf_scf_init(fmri) == -1) die(gettext("cannot connect to repository for %s\n"), fmri); /* * Since the sys_acct the privilege allows use of acctctl() regardless * of the accounting type, we check the smf(5) authorizations granted * to the user to determine whether the user is allowed to change the * configuration for this particular accounting type. */ if (!aconf_have_smf_auths()) die(gettext("insufficient authorization to change %s extended " "accounting configuration\n"), ac_type_name(type)); if (xflg) { /* * Turn off the specified accounting and close its file */ /* * Stop net logging before turning it off so that the last * set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging network " "information, error %d\n"), errno); } } state = AC_OFF; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot disable %s accounting"), ac_type_name(type)); if (acctctl(type | AC_FILE_SET, NULL, 0) == -1) die(gettext("cannot close %s accounting file\n"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_FILE); modified++; } if (enabled || disabled) { char *tracked, *untracked; ac_res_t *buf; /* * Enable/disable resources */ if ((buf = malloc(AC_BUFSIZE)) == NULL) die(gettext("not enough memory\n")); (void) memset(buf, 0, AC_BUFSIZE); if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) { free(buf); die(gettext("cannot obtain list of resources\n")); } if (disabled) { /* * Stop net logging before turning it off so that the * last set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, strcmp(disabled, "basic") == 0 ? DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging " "network information, error %d\n"), errno); } } str2buf(buf, disabled, AC_OFF, type); } else if (enabled) { str2buf(buf, enabled, AC_ON, type); } (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) { free(buf); die(gettext("cannot enable/disable %s accounting " "resources\n"), ac_type_name(type)); } (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type); untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type); if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1) die(gettext("cannot update %s property\n"), AC_PROP_TRACKED); if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1) die(gettext("cannot update %s property\n"), AC_PROP_UNTRACKED); free(tracked); free(untracked); free(buf); modified++; } if (file) { /* * Open new accounting file */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (open_exacct_file(file, type) == -1) { dladm_close(dld_handle); exit(E_ERROR); } if (aconf_set_string(AC_PROP_FILE, file) == -1) die(gettext("cannot update %s property\n"), AC_PROP_FILE); state = AC_ON; if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot enable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } /* * Let's get network logging started. We do this after turning on * accounting and opening the file so that we can start writing * immediately. */ if (enabled && (type & AC_NET)) { /* * Default logging interval for AC_NET is * ACCTADM_NET_LOG_INTERVAL. */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_start_usagelog(dld_handle, strcmp(enabled, "basic") == 0 ? DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to start logging " "network information, error %d\n"), errno); } } if (Dflg) { /* * Disable accounting */ /* * Stop net logging before turning it off so that the last * set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging " "network information, error %d\n"), errno); } } state = AC_OFF; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot disable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } if (Eflg) { /* * Enable accounting */ /* * Let's get network logging started. */ if (type & AC_NET) { /* * Default logging interval for AC_NET is * ACCTADM_NET_LOG_INTERVAL. */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_start_usagelog(dld_handle, DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to start logging " "network information, error %d\n"), errno); } } state = AC_ON; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot enable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL); if (modified) { char *smf_state; if (aconf_save() == -1) die(gettext("cannot save %s accounting " "configuration\n"), ac_type_name(type)); /* * Enable or disable the instance depending on the effective * configuration. If the effective configuration results in * extended accounting being 'on', the instance is enabled so * the configuration is applied at the next boot. */ smf_state = smf_get_state(fmri); aconf_init(&ac, type); if (ac.state == AC_ON || strcmp(ac.file, AC_STR_NONE) != 0 || strcmp(ac.tracked, AC_STR_NONE) != 0) { if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0) if (smf_enable_instance(fmri, 0) == -1) die(gettext("cannot enable %s\n"), fmri); } else { if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0) if (smf_disable_instance(fmri, 0) == -1) die(gettext("cannot disable %s\n"), fmri); } free(smf_state); } aconf_scf_fini(); dladm_close(dld_handle); return (E_SUCCESS); }
int main(int argc, char **argv) { int c; int updates = 0; char *usage = "Usage: %s [-v] [-f prom-device]" " [variable[=value] ...]"; eplist_t *elist; benv_des_t *bd; char *file = NULL; setpname(argv[0]); while ((c = getopt(argc, argv, "f:Itv")) != -1) switch (c) { case 'v': verbose++; break; case 'f': file = optarg; break; case 't': test++; break; default: exit(_error(NO_PERROR, usage, argv[0])); } (void) uname(&uts_buf); bd = new_bd(); init_benv(bd, file); map_benv(bd); if (bd->len) { parse_benv(bd); unmap_benv(bd); } elist = bd->elist; if (optind >= argc) { print_vars(elist); return (0); } else while (optind < argc) { /* * If "-" specified, read variables from stdin; * otherwise, process each argument as a variable * print or set request. */ if (strcmp(argv[optind], "-") == 0) { char *line; while ((line = get_line()) != NULL) updates += proc_var(line, elist); clearerr(stdin); } else updates += proc_var(argv[optind], elist); optind++; } /* * don't write benv if we are processing delayed writes since * it is likely that the delayed writes changes bootenv.rc anyway... */ if (updates) write_benv(bd); close_kbenv(); return (0); }