static int do_position(const char *cname, int argc, char **argv) { struct changer_position cmd; int val; /* * On a position command, we expect the following: * * <to ET> <to EU> [inv] * * where ET == element type and EU == element unit. */ ++argv; --argc; if (argc < 2) { warnx("%s: too few arguments", cname); goto usage; } else if (argc > 3) { warnx("%s: too many arguments", cname); goto usage; } (void) memset(&cmd, 0, sizeof(cmd)); /* <to ET> */ cmd.cp_type = parse_element_type(*argv); ++argv; --argc; /* <to EU> */ cmd.cp_unit = parse_element_unit(*argv); ++argv; --argc; /* Deal with optional command modifier. */ if (argc) { val = parse_special(*argv); switch (val) { case SW_INVERT: cmd.cp_flags |= CP_INVERT; break; default: errx(1, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOPOSITION, &cmd)) err(1, "%s: CHIOPOSITION", changer_name); return (0); usage: (void) fprintf(stderr, "usage: %s %s <to ET> <to EU> [inv]\n", getprogname(), cname); return (1); }
/* parse the whole string. $ and \ chars are replaced */ char *parse_special_string(const char *cmd, SERVER_REC *server, void *item, const char *data, int *arg_used) { char code, **arglist, *ret; GString *str; int need_free; g_return_val_if_fail(cmd != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); /* create the argument list */ arglist = g_strsplit(data, " ", -1); if (arg_used != NULL) *arg_used = FALSE; code = 0; str = g_string_new(NULL); while (*cmd != '\0') { if (code == '\\'){ switch (*cmd) { case 't': g_string_append_c(str, '\t'); break; case 'n': g_string_append_c(str, '\n'); break; default: g_string_append_c(str, *cmd); } code = 0; } else if (code == '$') { char *ret; ret = parse_special((char **) &cmd, server, item, arglist, &need_free, arg_used); if (ret != NULL) { g_string_append(str, ret); if (need_free) g_free(ret); } code = 0; } else { if (*cmd == '\\' || *cmd == '$') code = *cmd; else g_string_append_c(str, *cmd); } cmd++; } g_strfreev(arglist); ret = str->str; g_string_free(str, FALSE); return ret; }
/* returns TRUE if data is empty, or the data is a $variable which is empty */ static int data_is_empty(const char **data) { /* since we don't know the real argument list, assume there's always an argument in them */ static char *arglist[] = { "x", "x", "x", "x", "x", "x","x", "x", "x", "x", NULL }; SERVER_REC *server; const char *p; char *ret; int free_ret, empty; p = *data; while (*p == ' ') p++; if (*p == '}') { /* empty */ *data = p+1; return TRUE; } if (*p != '$') { /* not empty */ return FALSE; } /* variable - check if it's empty */ p++; server = active_win == NULL ? NULL : active_win->active_server != NULL ? active_win->active_server : active_win->connect_server; ret = parse_special((char **) &p, server, active_win == NULL ? NULL : active_win->active, arglist, &free_ret, NULL, 0); p++; while (*p == ' ') p++; empty = *p == '}' && (ret == NULL || *ret == '\0'); if (free_ret) g_free(ret); if (empty) { /* empty */ *data = p+1; return TRUE; } return FALSE; }
/* one child operation */ static void child_op(struct child_struct *child, const char *opname, const char *fname, const char *fname2, char **params, const char *status) { static struct dbench_op prev_op; struct dbench_op op; unsigned i; child->lasttime = timeval_current(); ZERO_STRUCT(op); op.child = child; op.op = opname; op.fname = fname; op.fname2 = fname2; op.status = status; for (i=0;i<sizeof(op.params)/sizeof(op.params[0]);i++) { switch (params[i][0]) { case '*': case '+': op.params[i] = parse_special(params[i], prev_op.params[i]); break; default: op.params[i] = params[i]?ival(params[i]):0; } } prev_op = op; if (strcasecmp(op.op, "Sleep") == 0) { nb_sleep(op.params[0]); return; } for (i=0;nb_ops->ops[i].name;i++) { if (strcasecmp(op.op, nb_ops->ops[i].name) == 0) { nb_ops->ops[i].fn(&op); finish_op(child, &child->ops[i]); return; } } printf("[%u] Unknown operation %s in pid %u\n", child->line, op.op, (unsigned)getpid()); }
/* append "variable" part in $variable, ie. not the contents of the variable */ static void theme_format_append_variable(GString *str, const char **format) { const char *orig; char *value, *args[1] = { NULL }; int free_ret; orig = *format; (*format)++; value = parse_special((char **) format, NULL, NULL, args, &free_ret, NULL, PARSE_FLAG_ONLY_ARGS); if (free_ret) g_free(value); if (**format != '\0') (*format)++; /* append the variable name */ value = g_strndup(orig, (int) (*format-orig)); g_string_append(str, value); g_free(value); }
int main() { char* input = NULL; char** arg_list = NULL; int status = 0; int args = 0; int mode = 0; char * spec_res = NULL; do { args = 0; input = NULL; arg_list = NULL; status = dsh_prompt( &input ); scanf( "%*1c" ); if( !status ) { status = parse_input( &args, input, &arg_list ); mode = parse_special( arg_list , &spec_res ); fflush(stdout); if( mode == -1 ) fprintf( stderr , "Parse error: Verify command and order of operators\n" ); else if( mode == 0 ) status = run_command( args , arg_list ); else status = run_special( spec_res , mode ); } if( input != NULL ) free( input ); if( arg_list != NULL ) free( arg_list ); }while( status < 2 ); return 0; }
static struct AstNode *parse_one( struct DomNode *dom, struct ParserState *state) { err_reset(); struct AstNode *node; if ((!err_state() && (node = parse_literal_atomic(dom, state))) || (!err_state() && (node = parse_symbol(dom, state))) || (!err_state() && (node = parse_special(dom, state))) || (!err_state() && (node = parse_func_call(dom, state))) || (!err_state() && (node = parse_literal_compound(dom, state)))) { if (state->acb) { state->acb(state->data, node, &dom->loc); } return node; } else { err_push_src( "PARSE", &dom->loc, "Failed parsing DOM node"); return NULL; } }
static int do_status(const char *cname, int argc, char **argv) { struct changer_element_status_request cmd; struct changer_params data; struct changer_element_status *ces; int i, chet, count, echet, flags, have_ucount, have_unit; int schet, ucount, unit; size_t size; flags = 0; ucount = 0; unit = 0; have_ucount = 0; have_unit = 0; /* * On a status command, we expect the following: * * [<ET> [unit [count]]] [voltags] * * where ET == element type. * * If we get no element-related arguments, we get the status of all * known element types. */ if (argc > 4) { warnx("%s: too many arguments", cname); usage(); /*NOTREACHED*/ } /* * Get params from changer. Specifically, we need the element * counts. */ (void)memset(&data, 0, sizeof(data)); if (ioctl(changer_fd, CHIOGPARAMS, &data)) err(EXIT_FAILURE, "%s: CHIOGPARAMS", changer_name); /* NOTREACHED */ schet = CHET_MT; echet = CHET_DT; for (; argc != 0; argc--, argv++) { /* * If we have the voltags modifier, it must be the * last argument. */ if (is_special(argv[0])) { if (argc != 1) { warnx("%s: malformed command line", cname); usage(); /*NOTREACHED*/ } if (parse_special(argv[0]) != SW_VOLTAGS) errx(EXIT_FAILURE, "%s: inappropriate special word: %s", cname, argv[0]); /* NOTREACHED */ flags |= CESR_VOLTAGS; continue; } /* * If we get an element type, we can't have specified * anything else. */ if (isdigit((unsigned char)*argv[0]) == 0) { if (schet == echet || flags != 0 || have_unit || have_ucount) { warnx("%s: malformed command line", cname); usage(); /*NOTREACHED*/ } schet = echet = parse_element_type(argv[0]); continue; } /* * We know we have a digit here. If we do, we must * have specified an element type. */ if (schet != echet) { warnx("%s: malformed command line", cname); usage(); /*NOTREACHED*/ } i = parse_element_unit(argv[0]); if (have_unit == 0) { unit = i; have_unit = 1; } else if (have_ucount == 0) { ucount = i; have_ucount = 1; } else { warnx("%s: malformed command line", cname); usage(); /*NOTREACHED*/ } } for (chet = schet; chet <= echet; ++chet) { switch (chet) { case CHET_MT: count = data.cp_npickers; break; case CHET_ST: count = data.cp_nslots; break; case CHET_IE: count = data.cp_nportals; break; case CHET_DT: count = data.cp_ndrives; break; default: /* To appease gcc -Wuninitialized. */ count = 0; } if (count == 0) { if (schet != echet) continue; else { (void)printf("%s: no %s elements\n", changer_name, elements[chet].et_name); return (0); } } /* * If we have a unit, we may or may not have a count. * If we don't have a unit, we don't have a count, either. * * Make sure both are initialized. */ if (have_unit) { if (have_ucount == 0) ucount = 1; } else { unit = 0; ucount = count; } if ((unit + ucount) > count) errx(EXIT_FAILURE, "%s: unvalid unit/count %d/%d", cname, unit, ucount); /* NOTREACHED */ size = ucount * sizeof(struct changer_element_status); /* Allocate storage for the status bytes. */ if ((ces = malloc(size)) == NULL) errx(EXIT_FAILURE, "can't allocate status storage"); /* NOTREACHED */ (void)memset(ces, 0, size); (void)memset(&cmd, 0, sizeof(cmd)); cmd.cesr_type = chet; cmd.cesr_unit = unit; cmd.cesr_count = ucount; cmd.cesr_flags = flags; cmd.cesr_data = ces; /* * Should we deal with this eventually? */ cmd.cesr_vendor_data = NULL; if (ioctl(changer_fd, CHIOGSTATUS, &cmd)) { free(ces); err(EXIT_FAILURE, "%s: CHIOGSTATUS", changer_name); /* NOTREACHED */ } /* Dump the status for each element of this type. */ for (i = 0; i < ucount; i++) { (void)printf("%s %d: ", elements[chet].et_name, unit + i); if ((ces[i].ces_flags & CESTATUS_STATUS_VALID) == 0) { (void)printf("status not available\n"); continue; } (void)printf("%s", bits_to_string(ces[i].ces_flags, CESTATUS_BITS)); if (ces[i].ces_flags & CESTATUS_XNAME_VALID) (void)printf(" (%s)", ces[i].ces_xname); (void)printf("\n"); if (ces[i].ces_flags & CESTATUS_PVOL_VALID) (void)printf("\tPrimary volume tag: %s " "ver. %d\n", ces[i].ces_pvoltag.cv_tag, ces[i].ces_pvoltag.cv_serial); if (ces[i].ces_flags & CESTATUS_AVOL_VALID) (void)printf("\tAlternate volume tag: %s " "ver. %d\n", ces[i].ces_avoltag.cv_tag, ces[i].ces_avoltag.cv_serial); if (ces[i].ces_flags & CESTATUS_FROM_VALID) (void)printf("\tFrom: %s %d\n", elements[ces[i].ces_from_type].et_name, ces[i].ces_from_unit); if (ces[i].ces_vendor_len) (void)printf("\tVendor-specific data size: " "%lu\n", (u_long)ces[i].ces_vendor_len); } free(ces); } return (0); }
static int do_exchange(const char *cname, int argc, char **argv) { struct changer_exchange_request cmd; int val; /* * On an exchange command, we expect the following: * * <src ET> <src EU> <dst1 ET> <dst1 EU> [<dst2 ET> <dst2 EU>] [inv1] [inv2] * * where ET == element type and EU == element unit. */ if (argc < 4) { warnx("%s: too few arguments", cname); usage(); /*NOTREACHED*/ } else if (argc > 8) { warnx("%s: too many arguments", cname); usage(); /*NOTREACHED*/ } (void)memset(&cmd, 0, sizeof(cmd)); /* <src ET> */ cmd.ce_srctype = parse_element_type(*argv); ++argv; --argc; /* <src EU> */ cmd.ce_srcunit = parse_element_unit(*argv); ++argv; --argc; /* <dst1 ET> */ cmd.ce_fdsttype = parse_element_type(*argv); ++argv; --argc; /* <dst1 EU> */ cmd.ce_fdstunit = parse_element_unit(*argv); ++argv; --argc; /* * If the next token is a special word or there are no more * arguments, then this is a case of simple exchange. * dst2 == src. */ if ((argc == 0) || is_special(*argv)) { cmd.ce_sdsttype = cmd.ce_srctype; cmd.ce_sdstunit = cmd.ce_srcunit; goto do_special; } /* <dst2 ET> */ cmd.ce_sdsttype = parse_element_type(*argv); ++argv; --argc; /* <dst2 EU> */ cmd.ce_sdstunit = parse_element_unit(*argv); ++argv; --argc; do_special: /* Deal with optional command modifiers. */ while (argc) { val = parse_special(*argv); ++argv; --argc; switch (val) { case SW_INVERT1: cmd.ce_flags |= CE_INVERT1; break; case SW_INVERT2: cmd.ce_flags |= CE_INVERT2; break; default: errx(EXIT_FAILURE, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOEXCHANGE, &cmd)) err(EXIT_FAILURE, "%s: CHIOEXCHANGE", changer_name); /* NOTREACHED */ return (0); }
static int do_move(const char *cname, int argc, char **argv) { struct changer_move_request cmd; int val; /* * On a move command, we expect the following: * * <from ET> <from EU> <to ET> <to EU> [inv] * * where ET == element type and EU == element unit. */ if (argc < 4) { warnx("%s: too few arguments", cname); usage(); /*NOTREACHED*/ } else if (argc > 5) { warnx("%s: too many arguments", cname); usage(); /*NOTREACHED*/ } (void)memset(&cmd, 0, sizeof(cmd)); /* <from ET> */ cmd.cm_fromtype = parse_element_type(*argv); ++argv; --argc; /* <from EU> */ cmd.cm_fromunit = parse_element_unit(*argv); ++argv; --argc; /* <to ET> */ cmd.cm_totype = parse_element_type(*argv); ++argv; --argc; /* <to EU> */ cmd.cm_tounit = parse_element_unit(*argv); ++argv; --argc; /* Deal with optional command modifier. */ if (argc) { val = parse_special(*argv); switch (val) { case SW_INVERT: cmd.cm_flags |= CM_INVERT; break; default: errx(EXIT_FAILURE, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOMOVE, &cmd)) err(EXIT_FAILURE, "%s: CHIOMOVE", changer_name); /* NOTREACHED */ return (0); }
/* SYNTAX: MSG [-<server tag>] [-channel | -nick] <targets> <message> */ static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item) { GHashTable *optlist; char *target, *origtarget, *msg; void *free_arg; int free_ret, target_type = SEND_TARGET_NICK; g_return_if_fail(data != NULL); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, "msg", &optlist, &target, &msg)) return; if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); server = cmd_options_get_server("msg", optlist, server); if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); origtarget = target; free_ret = FALSE; if (strcmp(target, ",") == 0 || strcmp(target, ".") == 0) { target = parse_special(&target, server, item, NULL, &free_ret, NULL, 0); if (target != NULL && *target == '\0') { if (free_ret) g_free(target); target = NULL; free_ret = FALSE; } } if (target != NULL) { if (strcmp(target, "*") == 0) { /* send to active channel/query */ if (item == NULL) cmd_param_error(CMDERR_NOT_JOINED); target_type = IS_CHANNEL(item) ? SEND_TARGET_CHANNEL : SEND_TARGET_NICK; target = (char *) window_item_get_target(item); } else if (g_hash_table_lookup(optlist, "channel") != NULL) target_type = SEND_TARGET_CHANNEL; else if (g_hash_table_lookup(optlist, "nick") != NULL) target_type = SEND_TARGET_NICK; else { /* Need to rely on server_ischannel(). If the protocol doesn't really know if it's channel or nick based on the name, it should just assume it's nick, because when typing text to channels it's always sent with /MSG -channel. */ target_type = server_ischannel(server, target) ? SEND_TARGET_CHANNEL : SEND_TARGET_NICK; } } if (target != NULL) { char **splitmsgs; char **tmp = NULL; char *singlemsg[] = { msg, NULL }; char *m; int n = 0; /* * If split_message is NULL, the server doesn't need to split * long messages. */ if (server->split_message != NULL) splitmsgs = tmp = server->split_message(server, target, msg); else splitmsgs = singlemsg; while ((m = splitmsgs[n++])) { signal_emit("server sendmsg", 4, server, target, m, GINT_TO_POINTER(target_type)); signal_emit(target_type == SEND_TARGET_CHANNEL ? "message own_public" : "message own_private", 4, server, m, target, origtarget); } g_strfreev(tmp); } else { signal_emit("message own_private", 4, server, msg, target, origtarget); } if (free_ret && target != NULL) g_free(target); cmd_params_free(free_arg); }
/* * Handles directory. */ void parse_dir(unsigned char *indir, struct detox_options *options) { unsigned char *new_file, *work; DIR *dir_handle; struct dirent *dir_entry; struct stat stat_info; int check_file, x; int err; err = lstat(indir, &stat_info); if (err == -1) { return; } if (!S_ISDIR(stat_info.st_mode)) { return; } new_file = (char *)malloc(strlen(indir) + 1024); if (new_file == NULL) { fprintf(stderr, "out of memory: %s\n", strerror(errno)); return; } dir_handle = opendir(indir); if (dir_handle == NULL) { fprintf(stderr, "unable to parse: %s\n", strerror(errno)); free(new_file); return; } dir_entry = readdir(dir_handle); while (dir_entry != NULL) { check_file = 1; for (x = 0; badfiles[x][0] != 0; x++) { if (strcmp(dir_entry->d_name, badfiles[x]) == 0) { check_file = 0; break; } } if (check_file) { sprintf(new_file, "%s/%s", indir, dir_entry->d_name); lstat(new_file, &stat_info); if (S_ISDIR(stat_info.st_mode)) { work = parse_file(new_file, options); if (options->recurse) { parse_dir(work, options); } free(work); } else if (S_ISREG(stat_info.st_mode)) { work = parse_file(new_file, options); free(work); } else if (options->special) { parse_special(new_file, options); } } dir_entry = readdir(dir_handle); } closedir(dir_handle); }
static int do_exchange(const char *cname, int argc, char **argv) { struct changer_exchange cmd; int val; /* * On an exchange command, we expect the following: * * <src ET> <src EU> <dst1 ET> <dst1 EU> [<dst2 ET> <dst2 EU>] [inv1] [inv2] * * where ET == element type and EU == element unit. */ ++argv; --argc; if (argc < 4) { warnx("%s: too few arguments", cname); goto usage; } else if (argc > 8) { warnx("%s: too many arguments", cname); goto usage; } (void) memset(&cmd, 0, sizeof(cmd)); /* <src ET> */ cmd.ce_srctype = parse_element_type(*argv); ++argv; --argc; /* Check for voltag virtual type */ if (CHET_VT == cmd.ce_srctype) { find_element(*argv, &cmd.ce_srctype, &cmd.ce_srcunit); } else { /* <from EU> */ cmd.ce_srcunit = parse_element_unit(*argv); } ++argv; --argc; /* <dst1 ET> */ cmd.ce_fdsttype = parse_element_type(*argv); ++argv; --argc; /* Check for voltag virtual type */ if (CHET_VT == cmd.ce_fdsttype) { find_element(*argv, &cmd.ce_fdsttype, &cmd.ce_fdstunit); } else { /* <from EU> */ cmd.ce_fdstunit = parse_element_unit(*argv); } ++argv; --argc; /* * If the next token is a special word or there are no more * arguments, then this is a case of simple exchange. * dst2 == src. */ if ((argc == 0) || is_special(*argv)) { cmd.ce_sdsttype = cmd.ce_srctype; cmd.ce_sdstunit = cmd.ce_srcunit; goto do_special; } /* <dst2 ET> */ cmd.ce_sdsttype = parse_element_type(*argv); ++argv; --argc; if (CHET_VT == cmd.ce_sdsttype) errx(1,"%s %s: voltag only makes sense as an element source", cname, *argv); /* <dst2 EU> */ cmd.ce_sdstunit = parse_element_unit(*argv); ++argv; --argc; do_special: /* Deal with optional command modifiers. */ while (argc) { val = parse_special(*argv); ++argv; --argc; switch (val) { case SW_INVERT1: cmd.ce_flags |= CE_INVERT1; break; case SW_INVERT2: cmd.ce_flags |= CE_INVERT2; break; default: errx(1, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOEXCHANGE, &cmd)) err(1, "%s: CHIOEXCHANGE", changer_name); return (0); usage: (void) fprintf(stderr, "usage: %s %s <src ET> <src EU> <dst1 ET> <dst1 EU>\n" " [<dst2 ET> <dst2 EU>] [inv1] [inv2]\n", getprogname(), cname); return (1); }
static int do_move(const char *cname, int argc, char **argv) { struct changer_move cmd; int val; /* * On a move command, we expect the following: * * <from ET> <from EU> <to ET> <to EU> [inv] * * where ET == element type and EU == element unit. */ ++argv; --argc; if (argc < 4) { warnx("%s: too few arguments", cname); goto usage; } else if (argc > 5) { warnx("%s: too many arguments", cname); goto usage; } (void) memset(&cmd, 0, sizeof(cmd)); /* <from ET> */ cmd.cm_fromtype = parse_element_type(*argv); ++argv; --argc; /* Check for voltag virtual type */ if (CHET_VT == cmd.cm_fromtype) { find_element(*argv, &cmd.cm_fromtype, &cmd.cm_fromunit); } else { /* <from EU> */ cmd.cm_fromunit = parse_element_unit(*argv); } ++argv; --argc; /* <to ET> */ cmd.cm_totype = parse_element_type(*argv); ++argv; --argc; /* Check for voltag virtual type, and report error */ if (CHET_VT == cmd.cm_totype) errx(1,"%s: voltag only makes sense as an element source", cname); /* <to EU> */ cmd.cm_tounit = parse_element_unit(*argv); ++argv; --argc; /* Deal with optional command modifier. */ if (argc) { val = parse_special(*argv); switch (val) { case SW_INVERT: cmd.cm_flags |= CM_INVERT; break; default: errx(1, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOMOVE, &cmd)) err(1, "%s: CHIOMOVE", changer_name); return (0); usage: (void) fprintf(stderr, "usage: %s %s " "<from ET> <from EU> <to ET> <to EU> [inv]\n", getprogname(), cname); return (1); }
static int do_move(char *cname, int argc, char *argv[]) { struct changer_move cmd; int val; /* * On a move command, we expect the following: * * <from ET> <from EU> <to ET> <to EU> [inv] * * where ET == element type and EU == element unit. */ ++argv; --argc; if (argc < 4) { warnx("%s: too few arguments", cname); goto usage; } else if (argc > 5) { warnx("%s: too many arguments", cname); goto usage; } bzero(&cmd, sizeof(cmd)); /* * Get the from ET and EU - we search for it if the ET is * "voltag", otherwise, we just use the ET and EU given to us. */ if (strcmp(*argv, "voltag") == 0) { ++argv; --argc; find_voltag(*argv, &cmd.cm_fromtype, &cmd.cm_fromunit); ++argv; --argc; } else { cmd.cm_fromtype = parse_element_type(*argv); ++argv; --argc; cmd.cm_fromunit = parse_element_unit(*argv); ++argv; --argc; } if (cmd.cm_fromtype == CHET_DT) check_source_drive(cmd.cm_fromunit); /* * Don't allow voltag on the to ET, using a volume * as a destination makes no sense on a move */ cmd.cm_totype = parse_element_type(*argv); ++argv; --argc; cmd.cm_tounit = parse_element_unit(*argv); ++argv; --argc; /* Deal with optional command modifier. */ if (argc) { val = parse_special(*argv); switch (val) { case SW_INVERT: cmd.cm_flags |= CM_INVERT; break; default: errx(1, "%s: inappropriate modifier `%s'", cname, *argv); /* NOTREACHED */ } } /* Send command to changer. */ if (ioctl(changer_fd, CHIOMOVE, &cmd)) err(1, "%s: CHIOMOVE", changer_name); return (0); usage: fprintf(stderr, "usage: %s %s " "<from ET> <from EU> <to ET> <to EU> [inv]\n", __progname, cname); return (1); }
static void cmd_msg(gchar *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { WINDOW_REC *window; CHANNEL_REC *channel; NICK_REC *nickrec; char *params, *target, *msg, *nickmode, *freestr, *newtarget; int free_ret; g_return_if_fail(data != NULL); params = cmd_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg); if (*target == '\0' || *msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*target == '=') { /* dcc msg - handled in fe-dcc.c */ g_free(params); return; } free_ret = FALSE; if (strcmp(target, ",") == 0 || strcmp(target, ".") == 0) newtarget = parse_special(&target, server, item, NULL, &free_ret, NULL); else if (strcmp(target, "*") == 0 && (irc_item_channel(item) || irc_item_query(item))) newtarget = item->name; else newtarget = target; if (newtarget == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, *target == ',' ? IRCTXT_NO_MSGS_GOT : IRCTXT_NO_MSGS_SENT); g_free(params); signal_stop(); return; } target = newtarget; if (server == NULL || !server->connected) cmd_param_error(CMDERR_NOT_CONNECTED); channel = channel_find(server, target); freestr = !free_ret ? NULL : target; if (*target == '@' && ischannel(target[1])) target++; /* Hybrid 6 feature, send msg to all ops in channel */ if (ischannel(*target)) { /* msg to channel */ nickrec = channel == NULL ? NULL : nicklist_find(channel, server->nick); nickmode = !settings_get_bool("show_nickmode") || nickrec == NULL ? "" : nickrec->op ? "@" : nickrec->voice ? "+" : " "; window = channel == NULL ? NULL : window_item_window((WI_ITEM_REC *) channel); if (window != NULL && window->active == (WI_ITEM_REC *) channel) { printformat(server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT, IRCTXT_OWN_MSG, server->nick, msg, nickmode); } else { printformat(server, target, MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT, IRCTXT_OWN_MSG_CHANNEL, server->nick, target, msg, nickmode); } } else { /* private message */ item = (WI_ITEM_REC *) privmsg_get_query(server, target, TRUE); printformat(server, target, MSGLEVEL_MSGS | MSGLEVEL_NOHILIGHT, item == NULL ? IRCTXT_OWN_MSG_PRIVATE : IRCTXT_OWN_MSG_PRIVATE_QUERY, target, msg, server->nick); } g_free_not_null(freestr); g_free(params); }
/* Parse and expand text after '$' character. return value has to be g_free()'d if `free_ret' is TRUE. */ char *parse_special(char **cmd, SERVER_REC *server, void *item, char **arglist, int *free_ret, int *arg_used) { static char **nested_orig_cmd = NULL; /* FIXME: KLUDGE! */ char command, *value; char align_pad; int align, align_flags; char *nest_value; int brackets, nest_free; *free_ret = FALSE; command = **cmd; (*cmd)++; switch (command) { case '[': /* alignment */ if (!get_alignment_args(cmd, &align, &align_flags, &align_pad) || **cmd == '\0') { (*cmd)--; return NULL; } break; default: command = 0; (*cmd)--; } nest_free = FALSE; nest_value = NULL; if (**cmd == '(') { /* subvariable */ int toplevel = nested_orig_cmd == NULL; if (toplevel) nested_orig_cmd = cmd; (*cmd)++; if (**cmd != '$') { /* ... */ nest_value = *cmd; } else { (*cmd)++; nest_value = parse_special(cmd, server, item, arglist, &nest_free, arg_used); } while ((*nested_orig_cmd)[1] != '\0') { (*nested_orig_cmd)++; if (**nested_orig_cmd == ')') break; } cmd = &nest_value; if (toplevel) nested_orig_cmd = NULL; } if (**cmd != '{') brackets = FALSE; else { /* special value is inside {...} (foo${test}bar -> fooXXXbar) */ (*cmd)++; brackets = TRUE; } value = get_special_value(cmd, server, item, arglist, free_ret, arg_used); if (**cmd == '\0') g_error("parse_special() : buffer overflow!"); if (brackets) { while (**cmd != '}' && (*cmd)[1] != '\0') (*cmd)++; } if (nest_free) g_free(nest_value); if (command == '[') { /* alignment */ char *p; if (value == NULL) return ""; p = get_alignment(value, align, align_flags, align_pad); if (*free_ret) g_free(value); *free_ret = TRUE; return p; } return value; }