/* * Make sure that arg is a proper C string that fits in a prname. * If strnlen(arg, PR_MAXNAMELEN) == PR_MAXNAMELEN, then arg either * doesn't have a terminating NUL or is too long, and we can't tell * which one in the current API. This code has always assumed that * the names presented to it are valid C strings, but for robustness * we can't depend on the server side guaranteeing that. Unfortunately, * the wire protocol uses a vector[PR_MAXNAMELEN] of char, so XDR will * not automatically fix up strings generated by the server. * * The inequality is just belt-and-suspenders and should be impossible. */ static_inline int check_length(prname arg) { if (strnlen(arg, PR_MAXNAMELEN) >= PR_MAXNAMELEN) return PRNAMETOOLONG; return 0; }
bool Notifier::sendHearbeat() { STACKLOG; char hearbeaturl[1024] = ""; char hearbeatdata[16384] = ""; memset(hearbeatdata, 0, 16384); sprintf(hearbeaturl, "%s/heartbeat/", REPO_URLPREFIX); if(Sequencer::getHeartbeatData(challenge, hearbeatdata)) return false; Logger::log(LOG_DEBUG, "heartbeat data (%d bytes long) sent to master server: >>%s<<", strnlen(hearbeatdata, 16384), hearbeatdata); if (HTTPPOST(hearbeaturl, hearbeatdata) < 0) return false; // the server gives back "failed" or "ok" return getResponse() == "ok"; }
// Save party to mysql int inter_party_tosql(struct party *p, int flag, int index) { // 'party' ('party_id','name','exp','item','leader_id','leader_char') char esc_name[NAME_LENGTH*2+1];// escaped party name int party_id; if( p == NULL || p->party_id == 0 ) return 0; party_id = p->party_id; #ifdef NOISY ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name); #endif Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH)); #ifndef TXT_SQL_CONVERT if( flag & PS_BREAK ) {// Break the party // we'll skip name-checking and just reset everyone with the same party id [celest] if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) ) Sql_ShowDebug(sql_handle); if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id) ) Sql_ShowDebug(sql_handle); //Remove from memory idb_remove(party_db_, party_id); return 1; } #endif //TXT_SQL_CONVERT if( flag & PS_CREATE ) {// Create party #ifndef TXT_SQL_CONVERT if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` " "(`name`, `exp`, `item`, `leader_id`, `leader_char`) " "VALUES ('%s', '%d', '%d', '%d', '%d')", party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) ) { Sql_ShowDebug(sql_handle); return 0; } party_id = p->party_id = (int)Sql_LastInsertId(sql_handle); #else //During conversion, you want to specify the id, and allow overwriting //(in case someone is re-running the process. if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` " "(`party_id`, `name`, `exp`, `item`, `leader_id`, `leader_char`) " "VALUES ('%d', '%s', '%d', '%d', '%d', '%d')", party_db, p->party_id, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) ) { Sql_ShowDebug(sql_handle); return 0; } #endif } #ifndef TXT_SQL_CONVERT if( flag & PS_BASIC ) {// Update party info. if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'", party_db, esc_name, p->exp, p->item, party_id) ) Sql_ShowDebug(sql_handle); } if( flag & PS_LEADER ) {// Update leader if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'", party_db, p->member[index].account_id, p->member[index].char_id, party_id) ) Sql_ShowDebug(sql_handle); } if( flag & PS_ADDMEMBER ) {// Add one party member. if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'", char_db, party_id, p->member[index].account_id, p->member[index].char_id) ) Sql_ShowDebug(sql_handle); } if( flag & PS_DELMEMBER ) {// Remove one party member. if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'", char_db, party_id, p->member[index].account_id, p->member[index].char_id) ) Sql_ShowDebug(sql_handle); } #endif //TXT_SQL_CONVERT if( save_log ) ShowInfo("Party Saved (%d - %s)\n", party_id, p->name); return 1; }
static int msm_fb_detect_panel(const char *name) { if (machine_is_msm8960_liquid()) { if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME, strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; } else { if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME, strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; #ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME, strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME, strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME, strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME, strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME, strnlen(MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME, PANEL_NAME_MAX_LEN))) { set_mdp_clocks_for_wuxga(); return 0; } if (!strncmp(name, MIPI_VIDEO_ORISE_720P_PANEL_NAME, strnlen(MIPI_VIDEO_ORISE_720P_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, MIPI_CMD_ORISE_720P_PANEL_NAME, strnlen(MIPI_CMD_ORISE_720P_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; #endif } if (!strncmp(name, HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; if (!strncmp(name, TVOUT_PANEL_NAME, strnlen(TVOUT_PANEL_NAME, PANEL_NAME_MAX_LEN))) return 0; pr_warning("%s: not supported '%s'", __func__, name); return -ENODEV; }
static PyObject *py_parse_tree(PyObject *self, PyObject *args) { char *text, *start, *end; int len, namelen; PyObject *ret, *item, *name; if (!PyArg_ParseTuple(args, "s#", &text, &len)) return NULL; /* TODO: currently this returns a list; if memory usage is a concern, * consider rewriting as a custom iterator object */ ret = PyList_New(0); if (ret == NULL) { return NULL; } start = text; end = text + len; while (text < end) { long mode; mode = strtol(text, &text, 8); if (*text != ' ') { PyErr_SetString(PyExc_ValueError, "Expected space"); Py_DECREF(ret); return NULL; } text++; namelen = strnlen(text, len - (text - start)); name = PyString_FromStringAndSize(text, namelen); if (name == NULL) { Py_DECREF(ret); return NULL; } if (text + namelen + 20 >= end) { PyErr_SetString(PyExc_ValueError, "SHA truncated"); Py_DECREF(ret); Py_DECREF(name); return NULL; } item = Py_BuildValue("(NlN)", name, mode, sha_to_pyhex((unsigned char *)text+namelen+1)); if (item == NULL) { Py_DECREF(ret); Py_DECREF(name); return NULL; } if (PyList_Append(ret, item) == -1) { Py_DECREF(ret); Py_DECREF(item); return NULL; } Py_DECREF(item); text += namelen+21; } return ret; }
// Add data 'd' identified by tag 'xntag' to the field entry 'f' int amp_add_fentry (struct automops *amp, struct fields *f, int xntag, char *d) { int i=0; unsigned long long int ulli=0; struct fields *g=NULL; switch(xntag) { case xml_index: i = (int) str2int(d); if (amp_checkindex(amp, i)) return ampInvalidIndex; // invalid index f->index = (int) i; break; case xml_name: if (ensure_single_word(d)>1) return ampInvalidName; // name must be single word g = amp_getfield_byname(amp, d); if (g!=NULL) return 1; // name already exists mz_strncpy(f->name, d, AUTOMOPS_MAX_NAME_LEN); break; case xml_desc: mz_strncpy(f->shortdesc, d, AUTOMOPS_MAX_SHORTDESC_LEN); break; case xml_longdesc: i = strnlen(d, 400); if (i==400) return ampDescTooLong; f->longdesc = (char*) malloc(i+1); mz_strncpy(f->longdesc, d, i+1); break; case xml_type: i = amp_str2type(d); if (i==-1) return ampInvalidType; f->type = i; break; case xml_constant: if (strncasecmp(d, "yes", 6)==0) f->constant=1; else if (strncasecmp(d, "no", 6)==0) f->constant=0; else return ampUnknownKeyword; // unknown keyword break; case xml_valname: if (ensure_single_word(d)>1) return ampSingleWordRequired; // name must be single word i = strnlen(d, AUTOMOPS_MAX_NAME_LEN); if (i==AUTOMOPS_MAX_NAME_LEN) return 1; // too long mz_strncpy(f->valname, d, AUTOMOPS_MAX_NAME_LEN); break; case xml_value: ulli = str2lint(d); if (ulli>0xffffffff) return ampRangeError; f->val = (u_int32_t) ulli; break; case xml_min: ulli = str2lint(d); if (ulli>0xffffffff) return ampRangeError; f->min = (u_int32_t) ulli; break; case xml_max: ulli = str2lint(d); if (ulli>0xffffffff) return ampRangeError; if (ulli<f->min) return 1; // max must be greater or equal min f->max = (u_int32_t) ulli; break; case xml_tlvt: ulli = str2lint(d); if (ulli>0xffffffff) return ampRangeError; f->tlv_type = (u_int32_t) ulli; break; case xml_tlvl: ulli = str2lint(d); if (ulli>0xffffffff) return ampRangeError; f->tlv_len = (u_int32_t) ulli; break; case xml_lshift: i = (int) str2int(d); if (i>7) return ampRangeError; f->leftshift=i; break; default: return ampUnknownTag; // unknown tag } return 0; }
/* checks the individual attributes of the tuple */ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block, int i, char *buffer) { IndexTuple tuple; uint32 nerrs = 0; int j, off; bits8 * bitmap; BTPageOpaque opaque; ereport(DEBUG2,(errmsg("[%d:%d] checking attributes for the tuple", block, i))); /* get the index tuple and info about the page */ tuple = (IndexTuple)(buffer + header->pd_linp[i].lp_off); opaque = (BTPageOpaque)(buffer + header->pd_special); /* current attribute offset - always starts at (buffer + off) */ off = header->pd_linp[i].lp_off + IndexInfoFindDataOffset(tuple->t_info); ereport(DEBUG3,(errmsg("[%d:%d] tuple has %d attributes", block, (i+1), RelationGetNumberOfAttributes(rel)))); bitmap = (bits8*)(buffer + header->pd_linp[i].lp_off + sizeof(IndexTupleData)); /* TODO This is mostly copy'n'paste from check_heap_tuple_attributes, so maybe it could be refactored to share the code. */ /* For left-most tuples on non-leaf pages, there are no data actually (see src/backend/access/nbtree/README, last paragraph in section "Notes About Data Representation") Use P_LEFTMOST/P_ISLEAF to identify such cases (for the leftmost item only) and set len = 0. */ if (P_LEFTMOST(opaque) && (! P_ISLEAF(opaque)) && (i == 0)) { ereport(DEBUG3, (errmsg("[%d:%d] leftmost tuple on non-leaf block => no data, skipping", block, i))); return nerrs; } /* check all the index attributes */ for (j = 0; j < rel->rd_att->natts; j++) { /* default length of the attribute */ int len = rel->rd_att->attrs[j]->attlen; /* copy from src/backend/commands/analyze.c */ bool is_varlena = (!rel->rd_att->attrs[j]->attbyval && len == -1); bool is_varwidth = (!rel->rd_att->attrs[j]->attbyval && len < 0); /* thus it's "len = -2" */ /* if the attribute is marked as NULL (in the tuple header), skip to the next attribute */ if (IndexTupleHasNulls(tuple) && att_isnull(j, bitmap)) { ereport(DEBUG3, (errmsg("[%d:%d] attribute '%s' is NULL (skipping)", block, (i+1), rel->rd_att->attrs[j]->attname.data))); continue; } /* fix the alignment (see src/include/access/tupmacs.h) */ off = att_align_pointer(off, rel->rd_att->attrs[j]->attalign, rel->rd_att->attrs[j]->attlen, buffer+off); if (is_varlena) { /* other interesting macros (see postgres.h) - should do something about those ... VARATT_IS_COMPRESSED(PTR) VARATT_IS_4B_C(PTR) VARATT_IS_EXTERNAL(PTR) VARATT_IS_1B_E(PTR) VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR) VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR)) */ len = VARSIZE_ANY(buffer + off); if (len < 0) { ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has negative length < 0 (%d)", block, (i+1), rel->rd_att->attrs[j]->attname.data, len))); ++nerrs; break; } if (VARATT_IS_COMPRESSED(buffer + off)) { /* the raw length should be less than 1G (and positive) */ if ((VARRAWSIZE_4B_C(buffer + off) < 0) || (VARRAWSIZE_4B_C(buffer + off) > 1024*1024)) { ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has invalid length %d (should be between 0 and 1G)", block, (i+1), rel->rd_att->attrs[j]->attname.data, VARRAWSIZE_4B_C(buffer + off)))); ++nerrs; /* no break here, this does not break the page structure - we may check the other attributes */ } } /* FIXME Check if the varlena value may be detoasted. */ } else if (is_varwidth) { /* get the C-string length (at most to the end of tuple), +1 as it does not include '\0' at the end */ /* if the string is not properly terminated, then this returns 'remaining space + 1' so it's detected */ len = strnlen(buffer + off, header->pd_linp[i].lp_off + len + header->pd_linp[i].lp_len - off) + 1; } /* Check if the length makes sense (is not negative and does not overflow * the tuple end, stop validating the other rows (we don't know where to * continue anyway). */ if (off + len > (header->pd_linp[i].lp_off + header->pd_linp[i].lp_len)) { ereport(WARNING, (errmsg("[%d:%d] attribute '%s' (off=%d len=%d) overflows tuple end (off=%d, len=%d)", block, (i+1), rel->rd_att->attrs[j]->attname.data, off, len, header->pd_linp[i].lp_off, header->pd_linp[i].lp_len))); ++nerrs; break; } /* skip to the next attribute */ off += len; ereport(DEBUG3,(errmsg("[%d:%d] attribute '%s' len=%d", block, (i+1), rel->rd_att->attrs[j]->attname.data, len))); } ereport(DEBUG3,(errmsg("[%d:%d] last attribute ends at %d, tuple ends at %d", block, (i+1), off, header->pd_linp[i].lp_off + header->pd_linp[i].lp_len))); /* after the last attribute, the offset should be exactly the same as the end of the tuple */ if (MAXALIGN(off) != header->pd_linp[i].lp_off + header->pd_linp[i].lp_len) { ereport(WARNING, (errmsg("[%d:%d] the last attribute ends at %d but the tuple ends at %d", block, (i+1), off, header->pd_linp[i].lp_off + header->pd_linp[i].lp_len))); ++nerrs; } return nerrs; }
int libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) { struct socket *so; struct ifreq ifr; int nob; int rc; __u32 val; CFS_DECL_FUNNEL_DATA; CFS_NET_IN; rc = socreate(PF_INET, &so, SOCK_STREAM, 0); CFS_NET_EX; if (rc != 0) { CERROR ("Can't create socket: %d\n", rc); return (-rc); } nob = strnlen(name, IFNAMSIZ); if (nob == IFNAMSIZ) { CERROR("Interface name %s too long\n", name); rc = -EINVAL; goto out; } CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ); strcpy(ifr.ifr_name, name); CFS_NET_IN; rc = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ifr, current_proc()); CFS_NET_EX; if (rc != 0) { CERROR("Can't get flags for interface %s\n", name); goto out; } if ((ifr.ifr_flags & IFF_UP) == 0) { CDEBUG(D_NET, "Interface %s down\n", name); *up = 0; *ip = *mask = 0; goto out; } *up = 1; strcpy(ifr.ifr_name, name); *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin(); CFS_NET_IN; rc = ifioctl(so, SIOCGIFADDR, (caddr_t)&ifr, current_proc()); CFS_NET_EX; if (rc != 0) { CERROR("Can't get IP address for interface %s\n", name); goto out; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *ip = ntohl(val); strcpy(ifr.ifr_name, name); *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin(); CFS_NET_IN; rc = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ifr, current_proc()); CFS_NET_EX; if (rc != 0) { CERROR("Can't get netmask for interface %s\n", name); goto out; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *mask = ntohl(val); out: CFS_NET_IN; soclose(so); CFS_NET_EX; return -rc; }
int libcfs_ipif_enumerate (char ***namesp) { /* Allocate and fill in 'names', returning # interfaces/error */ char **names; int toobig; int nalloc; int nfound; struct socket *so; struct ifreq *ifr; struct ifconf ifc; int rc; int nob; int i; CFS_DECL_FUNNEL_DATA; CFS_NET_IN; rc = socreate(PF_INET, &so, SOCK_STREAM, 0); CFS_NET_EX; if (rc != 0) { CERROR ("Can't create socket: %d\n", rc); return (-rc); } nalloc = 16; /* first guess at max interfaces */ toobig = 0; for (;;) { if (nalloc * sizeof(*ifr) > PAGE_CACHE_SIZE) { toobig = 1; nalloc = PAGE_CACHE_SIZE/sizeof(*ifr); CWARN("Too many interfaces: only enumerating first %d\n", nalloc); } LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr)); if (ifr == NULL) { CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc); rc = -ENOMEM; goto out0; } ifc.ifc_buf = (char *)ifr; ifc.ifc_len = nalloc * sizeof(*ifr); CFS_NET_IN; rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc()); CFS_NET_EX; if (rc < 0) { CERROR ("Error %d enumerating interfaces\n", rc); goto out1; } nfound = ifc.ifc_len/sizeof(*ifr); LASSERT (nfound <= nalloc); if (nfound < nalloc || toobig) break; LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); nalloc *= 2; } if (nfound == 0) goto out1; LIBCFS_ALLOC(names, nfound * sizeof(*names)); if (names == NULL) { rc = -ENOMEM; goto out1; } /* NULL out all names[i] */ memset (names, 0, nfound * sizeof(*names)); for (i = 0; i < nfound; i++) { nob = strnlen (ifr[i].ifr_name, IFNAMSIZ); if (nob == IFNAMSIZ) { /* no space for terminating NULL */ CERROR("interface name %.*s too long (%d max)\n", nob, ifr[i].ifr_name, IFNAMSIZ); rc = -ENAMETOOLONG; goto out2; } LIBCFS_ALLOC(names[i], IFNAMSIZ); if (names[i] == NULL) { rc = -ENOMEM; goto out2; } memcpy(names[i], ifr[i].ifr_name, nob); names[i][nob] = 0; } *namesp = names; rc = nfound; out2: if (rc < 0) libcfs_ipif_free_enumeration(names, nfound); out1: LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); out0: CFS_NET_IN; soclose(so); CFS_NET_EX; return rc; }
/* Interface looking up using infamous SIOCGIFCONF. */ static int interface_list_ioctl (void) { int ret; int sock; #define IFNUM_BASE 32 int ifnum; struct ifreq *ifreq; struct ifconf ifconf; struct interface_FOO *ifp; int n; int lastlen; /* Normally SIOCGIFCONF works with AF_INET socket. */ sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock < 0) { zlog_warn ("Can't make AF_INET socket stream: %s", safe_strerror (errno)); return -1; } /* Set initial ifreq count. This will be double when SIOCGIFCONF fail. Solaris has SIOCGIFNUM. */ #ifdef SIOCGIFNUM ret = ioctl (sock, SIOCGIFNUM, &ifnum); if (ret < 0) ifnum = IFNUM_BASE; else ifnum++; #else ifnum = IFNUM_BASE; #endif /* SIOCGIFNUM */ ifconf.ifc_buf = NULL; lastlen = 0; /* Loop until SIOCGIFCONF success. */ for (;;) { ifconf.ifc_len = sizeof (struct ifreq) * ifnum; ifconf.ifc_buf = XREALLOC(MTYPE_TMP, ifconf.ifc_buf, ifconf.ifc_len); ret = ioctl(sock, SIOCGIFCONF, &ifconf); if (ret < 0) { zlog_warn ("SIOCGIFCONF: %s", safe_strerror(errno)); goto end; } /* Repeatedly get info til buffer fails to grow. */ if (ifconf.ifc_len > lastlen) { lastlen = ifconf.ifc_len; ifnum += 10; continue; } /* Success. */ break; } /* Allocate interface. */ ifreq = ifconf.ifc_req; #ifdef OPEN_BSD for (n = 0; n < ifconf.ifc_len; ) { int size; ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n); ifp = if_get_by_name_len(ifreq->ifr_name, strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name))); if_add_update (ifp); size = ifreq->ifr_addr.sa_len; if (size < sizeof (ifreq->ifr_addr)) size = sizeof (ifreq->ifr_addr); size += sizeof (ifreq->ifr_name); n += size; } #else for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) { ifp = if_get_by_name_len(ifreq->ifr_name, strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name))); if_add_update (ifp); ifreq++; } #endif /* OPEN_BSD */ end: close (sock); XFREE (MTYPE_TMP, ifconf.ifc_buf); return ret; }
int libcfs_ipif_enumerate (char ***namesp) { /* Allocate and fill in 'names', returning # interfaces/error */ char **names; int toobig; int nalloc; int nfound; socket_t so; struct ifreq *ifr; struct ifconf ifc; int rc; int nob; int i; rc = -sock_socket(PF_INET, SOCK_STREAM, 0, NULL, NULL, &so); if (rc != 0) { CERROR ("Can't create socket: %d\n", rc); return (rc); } nalloc = 16; /* first guess at max interfaces */ toobig = 0; for (;;) { if (nalloc * sizeof(*ifr) > PAGE_CACHE_SIZE) { toobig = 1; nalloc = PAGE_CACHE_SIZE/sizeof(*ifr); CWARN("Too many interfaces: only enumerating first %d\n", nalloc); } LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr)); if (ifr == NULL) { CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc); rc = -ENOMEM; goto out0; } ifc.ifc_buf = (char *)ifr; ifc.ifc_len = nalloc * sizeof(*ifr); #if 1 /* * XXX Liang: * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in * kernel space because it always try to copy result to userspace. * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...). * I've created a bug for Apple, let's wait... */ nfound = 0; for (i = 0; i < 16; i++) { struct ifreq en; bzero(&en, sizeof(en)); snprintf(en.ifr_name, IFNAMSIZ, "en%d", i); rc = -sock_ioctl (so, SIOCGIFFLAGS, &en); if (rc != 0) continue; strcpy(ifr[nfound++].ifr_name, en.ifr_name); } #else /* NOT in using now */ rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc); if (rc < 0) { CERROR ("Error %d enumerating interfaces\n", rc); goto out1; } nfound = ifc.ifc_len/sizeof(*ifr); LASSERT (nfound <= nalloc); #endif if (nfound < nalloc || toobig) break; LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); nalloc *= 2; } if (nfound == 0) goto out1; LIBCFS_ALLOC(names, nfound * sizeof(*names)); if (names == NULL) { rc = -ENOMEM; goto out1; } /* NULL out all names[i] */ memset (names, 0, nfound * sizeof(*names)); for (i = 0; i < nfound; i++) { nob = strnlen (ifr[i].ifr_name, IFNAMSIZ); if (nob == IFNAMSIZ) { /* no space for terminating NULL */ CERROR("interface name %.*s too long (%d max)\n", nob, ifr[i].ifr_name, IFNAMSIZ); rc = -ENAMETOOLONG; goto out2; } LIBCFS_ALLOC(names[i], IFNAMSIZ); if (names[i] == NULL) { rc = -ENOMEM; goto out2; } memcpy(names[i], ifr[i].ifr_name, nob); names[i][nob] = 0; } *namesp = names; rc = nfound; out2: if (rc < 0) libcfs_ipif_free_enumeration(names, nfound); out1: LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); out0: sock_close(so); return rc; }
/* Get or Set the username for the fko context spa data. */ int fko_set_username(fko_ctx_t ctx, const char * const spoof_user) { char *username = NULL; int res = FKO_SUCCESS, is_user_heap_allocated=0; #if HAVE_LIBFIU fiu_return_on("fko_set_username_init", FKO_ERROR_CTX_NOT_INITIALIZED); #endif /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return FKO_ERROR_CTX_NOT_INITIALIZED; /* If spoof_user was not passed in, check for a SPOOF_USER enviroment * variable. If it is set, use its value. */ if(spoof_user != NULL && spoof_user[0] != '\0') { #if HAVE_LIBFIU fiu_return_on("fko_set_username_strdup", FKO_ERROR_MEMORY_ALLOCATION); #endif username = strdup(spoof_user); if(username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); is_user_heap_allocated = 1; } else username = getenv("SPOOF_USER"); /* Try to get the username from the system. */ if(username == NULL) { /* Since we've already tried looking at an env variable, try * LOGNAME next (and the cuserid() man page recommends this) */ if((username = getenv("LOGNAME")) == NULL) { #ifdef _XOPEN_SOURCE /* cuserid will return the effective user (i.e. su or setuid). */ username = cuserid(NULL); #else username = getlogin(); #endif /* if we still didn't get a username, continue falling back */ if(username == NULL) { if((username = getenv("USER")) == NULL) { username = strdup("NO_USER"); if(username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); is_user_heap_allocated = 1; } } } } /* Truncate the username if it is too long. */ if(strnlen(username, MAX_SPA_USERNAME_SIZE) == MAX_SPA_USERNAME_SIZE) *(username + MAX_SPA_USERNAME_SIZE - 1) = '\0'; if((res = validate_username(username)) != FKO_SUCCESS) { if(is_user_heap_allocated == 1) free(username); #if HAVE_LIBFIU fiu_return_on("fko_set_username_valuser", FKO_ERROR_INVALID_DATA); #endif return res; } /* Just in case this is a subsquent call to this function. We * do not want to be leaking memory. */ if(ctx->username != NULL) free(ctx->username); ctx->username = strdup(username); ctx->state |= FKO_DATA_MODIFIED; if(is_user_heap_allocated == 1) free(username); if(ctx->username == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); }
/* Note: caller must free return buffer */ char * build_path_from_dentry(struct dentry *direntry) { struct dentry *temp; int namelen; int dfsplen; char *full_path; char dirsep; struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); unsigned seq; dirsep = CIFS_DIR_SEP(cifs_sb); if (tcon->Flags & SMB_SHARE_IS_IN_DFS) dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; cifs_bp_rename_retry: namelen = dfsplen; seq = read_seqbegin(&rename_lock); rcu_read_lock(); for (temp = direntry; !IS_ROOT(temp);) { namelen += (1 + temp->d_name.len); temp = temp->d_parent; if (temp == NULL) { cifs_dbg(VFS, "corrupt dentry\n"); rcu_read_unlock(); return NULL; } } rcu_read_unlock(); full_path = kmalloc(namelen+1, GFP_KERNEL); if (full_path == NULL) return full_path; full_path[namelen] = 0; /* trailing null */ rcu_read_lock(); for (temp = direntry; !IS_ROOT(temp);) { spin_lock(&temp->d_lock); namelen -= 1 + temp->d_name.len; if (namelen < 0) { spin_unlock(&temp->d_lock); break; } else { full_path[namelen] = dirsep; strncpy(full_path + namelen + 1, temp->d_name.name, temp->d_name.len); cifs_dbg(FYI, "name: %s\n", full_path + namelen); } spin_unlock(&temp->d_lock); temp = temp->d_parent; if (temp == NULL) { cifs_dbg(VFS, "corrupt dentry\n"); rcu_read_unlock(); kfree(full_path); return NULL; } } rcu_read_unlock(); if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { cifs_dbg(FYI, "did not end path lookup where expected. namelen=%ddfsplen=%d\n", namelen, dfsplen); /* presumably this is only possible if racing with a rename of one of the parent directories (we can not lock the dentries above us to prevent this, but retrying should be harmless) */ kfree(full_path); goto cifs_bp_rename_retry; } /* DIR_SEP already set for byte 0 / vs \ but not for subsequent slashes in prepath which currently must be entered the right way - not sure if there is an alternative since the '\' is a valid posix character so we can not switch those safely to '/' if any are found in the middle of the prepath */ /* BB test paths to Windows with '/' in the midst of prepath */ if (dfsplen) { strncpy(full_path, tcon->treeName, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { if (full_path[i] == '\\') full_path[i] = '/'; } } } return full_path; }
/* Note: caller must free return buffer */ char * build_path_from_dentry(struct dentry *direntry) { struct dentry *temp; int namelen; int pplen; int dfsplen; char *full_path; char dirsep; struct cifs_sb_info *cifs_sb; if (direntry == NULL) return NULL; /* not much we can do if dentry is freed and we need to reopen the file after it was closed implicitly when the server crashed */ cifs_sb = CIFS_SB(direntry->d_sb); dirsep = CIFS_DIR_SEP(cifs_sb); pplen = cifs_sb->prepathlen; if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); else dfsplen = 0; cifs_bp_rename_retry: namelen = pplen + dfsplen; for (temp = direntry; !IS_ROOT(temp);) { namelen += (1 + temp->d_name.len); temp = temp->d_parent; if (temp == NULL) { cERROR(1, ("corrupt dentry")); return NULL; } } full_path = kmalloc(namelen+1, GFP_KERNEL); if (full_path == NULL) return full_path; full_path[namelen] = 0; /* trailing null */ for (temp = direntry; !IS_ROOT(temp);) { namelen -= 1 + temp->d_name.len; if (namelen < 0) { break; } else { full_path[namelen] = dirsep; strncpy(full_path + namelen + 1, temp->d_name.name, temp->d_name.len); cFYI(0, ("name: %s", full_path + namelen)); } temp = temp->d_parent; if (temp == NULL) { cERROR(1, ("corrupt dentry")); kfree(full_path); return NULL; } } if (namelen != pplen + dfsplen) { cERROR(1, ("did not end path lookup where expected namelen is %d", namelen)); /* presumably this is only possible if racing with a rename of one of the parent directories (we can not lock the dentries above us to prevent this, but retrying should be harmless) */ kfree(full_path); goto cifs_bp_rename_retry; } /* DIR_SEP already set for byte 0 / vs \ but not for subsequent slashes in prepath which currently must be entered the right way - not sure if there is an alternative since the '\' is a valid posix character so we can not switch those safely to '/' if any are found in the middle of the prepath */ /* BB test paths to Windows with '/' in the midst of prepath */ if (dfsplen) { strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { if (full_path[i] == '\\') full_path[i] = '/'; } } } strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen); return full_path; }
// Creates an independent automops element for mops // (it will be not part of any linked list so, next=prev=NULL) // // RETURN VALUE: - Pointer to the cloned automops // - NULL upon failure // struct automops * automops_clone_automops(struct automops * amp) { struct automops *new_automops; struct fields *f, *g, *h=NULL; int i; // Allocate memory new_automops = (struct automops *) malloc(sizeof(struct automops)); if (new_automops==NULL) { fprintf(stderr, "MZ alert: cannot create new automops element - memory full?\n"); return NULL; // memory full? } // Copy the automops items new_automops->next = NULL; new_automops->prev = NULL; strncpy(new_automops->name, amp->name, AUTOMOPS_MAX_NAME_LEN); strncpy(new_automops->desc, amp->desc, AUTOMOPS_MAX_SHORTDESC_LEN); new_automops->layers_on = amp->layers_on; new_automops->layers_off = amp->layers_off; new_automops->etype = amp->etype; new_automops->proto = amp->proto; for (i=0; i<6; i++) { new_automops->da[i] = amp->da[i]; // dst mac new_automops->sa[i] = amp->sa[i]; // src mac } new_automops->DA = amp->DA; // dst IP new_automops->SA = amp->SA; // src IP new_automops->dp = amp->dp; // dst port new_automops->sp = amp->sp; // src port new_automops->defined_externally = amp->defined_externally; new_automops->payload_type = amp->payload_type; if (amp->payload_s) { new_automops->payload = (char*) malloc(amp->payload_s); if (new_automops->payload==NULL) { fprintf(stderr, "MZ alert: cannot create new automops payload element - memory full?\n"); return NULL; // memory full? } memcpy((void*) new_automops->payload, amp->payload, amp->payload_s); } new_automops->used = amp->used; //////////////////////////////////////////////////////////////////////////////////////////////// // // Copy the fields list // new_automops->field = NULL; for (f=amp->field; f!=NULL; f=f->next) { g = (struct fields *) malloc(sizeof(struct fields)); if (g==NULL) { fprintf(stderr, "MZ alert: cannot create new field element - memory full?\n"); return NULL; // memory full? } if (new_automops->field==NULL) { // first element new_automops->field = g; h = g; } else { // next elements h->next = g; h = g; } // copy all data. From here on 'h' is the new one, 'f' is the existing one mz_strncpy(h->name, f->name, AUTOMOPS_MAX_NAME_LEN); mz_strncpy(h->shortdesc, f->shortdesc, AUTOMOPS_MAX_SHORTDESC_LEN); mz_strncpy(h->valname, f->valname, AUTOMOPS_MAX_NAME_LEN); if (f->longdesc!=NULL) { h->longdesc = (char*) malloc(strnlen(f->longdesc, 1600)); // 80 chars x 20 lines should be enough if (h->longdesc == NULL) { fprintf(stderr, "MZ alert: cannot allocate memory!\n"); return NULL; // memory full? } strncpy(h->longdesc, f->longdesc, 1600); } if (f->str_s) { h->str_s = f->str_s; h->str = (u_int8_t *) malloc(f->str_s); if (h->str == NULL) { fprintf(stderr, "MZ alert: cannot allocate memory!\n"); return NULL; // memory full? } memcpy((void*) h->str, (void*) f->str, f->str_s); } h->constant = f->constant; h->type = f->type; h->tlv_type = f->tlv_type; h->tlv_len = f->tlv_len; h->val = f->val; h->min = f->min; h->max = f->max; h->leftshift = f->leftshift; h->index = f->index; } return new_automops; }
int libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask) { struct ifreq ifr; socket_t so; __u32 val; int nob; int rc; rc = -sock_socket(PF_INET, SOCK_STREAM, 0, NULL, NULL, &so); if (rc != 0) { CERROR ("Can't create socket: %d\n", rc); return rc; } nob = strnlen(name, IFNAMSIZ); if (nob == IFNAMSIZ) { CERROR("Interface name %s too long\n", name); rc = -EINVAL; goto out; } CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ); bzero(&ifr, sizeof(ifr)); strcpy(ifr.ifr_name, name); rc = -sock_ioctl (so, SIOCGIFFLAGS, &ifr); if (rc != 0) { CERROR("Can't get flags for interface %s\n", name); goto out; } if ((ifr.ifr_flags & IFF_UP) == 0) { CDEBUG(D_NET, "Interface %s down\n", name); *up = 0; *ip = *mask = 0; goto out; } *up = 1; bzero(&ifr, sizeof(ifr)); strcpy(ifr.ifr_name, name); *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin(); rc = -sock_ioctl(so, SIOCGIFADDR, &ifr); if (rc != 0) { CERROR("Can't get IP address for interface %s\n", name); goto out; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *ip = ntohl(val); bzero(&ifr, sizeof(ifr)); strcpy(ifr.ifr_name, name); *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin(); rc = -sock_ioctl(so, SIOCGIFNETMASK, &ifr); if (rc != 0) { CERROR("Can't get netmask for interface %s\n", name); goto out; } val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; *mask = ntohl(val); out: sock_close(so); return rc; }
// Add data 'd' identified by tag 'xntag' to the automops entry 'amp'. // // RETURN VALUE: 0 upon success, 1 upon failure // int amp_add_pentry (struct automops *amp, int xntag, char *d) { int i=0; char *tok; u_int8_t x[MAX_MOPS_MSG_SIZE]; struct automops *g; switch (xntag) { case xml_name: if (strpbrk(d," \t")!=NULL) return ampInvalidName; // name must not consist of multiple words! g = amp_getamp_byname(amp_head, d); if (g!=NULL) return ampDuplicateName; // name already exists! mz_strncpy(amp->name, d, AUTOMOPS_MAX_NAME_LEN); if (verbose==2) { fprintf(stderr, "Adding protocol '%s'\n", amp->name); } break; case xml_desc: mz_strncpy(amp->desc, d, AUTOMOPS_MAX_SHORTDESC_LEN); break; case xml_requires: i = mops_str2layers(d); if (i==-1) return ampInvalidLayer; if ((i&MOPS_UDP) && (i&MOPS_TCP)) return ampTCPandUDP; // cannot require both! amp->layers_on |= i; // must be ORed because several same-tags allowed break; case xml_conflicts: i = mops_str2layers(d); if (i==-1) return ampInvalidLayer; amp->layers_off |= i; // must be ORed because several same-tags allowed break; case xml_payloadtype: // 0=none, 1=ascii, 2=hex, 3=any tok = strtok (d," "); while (tok!=NULL) { if (strncasecmp("allowed", d, 10)==0) { // only change if payload_type is still zero if (amp->payload_type==0) amp->payload_type=3; } else if (strncasecmp("ascii", d, 10)==0) amp->payload_type|=1; else if (strncasecmp("hex", d, 10)==0) amp->payload_type|=2; else if (strncasecmp("any", d, 10)==0) amp->payload_type=3; else if (strncasecmp("none", d, 10)==0) amp->payload_type=0; else return ampPayloadType; // unknown tok=strtok(NULL, " "); } break; case xml_payload: i=strnlen(d,MAX_MOPS_MSG_SIZE); if (i==MAX_MOPS_MSG_SIZE) return ampPayloadLen; amp->payload = (char*) malloc (i+1); mz_strncpy(amp->payload, d, i+1); amp->payload_s = i; break; case xml_payloadhex: i=str2hex(d,x,MAX_MOPS_MSG_SIZE); if (i==MAX_MOPS_MSG_SIZE) return ampPayloadLen; if (i==-1) return 1; amp->payload = (char*) malloc (i+1); memcpy((void*)amp->payload, (void*) x, i); amp->payload_s = i; break; default: return ampUnknownTag; } return 0; }
/** * Check/authentication of a connection. * @param sd: string (atm:md5key or dbpass) * @param isServer: string (atm:md5key or dbpass) * @return : * -1: success * 0: unregistered id; * 1: incorrect pass; * 2: expired id * 3: blacklisted (or registration limit exceeded if new acc); * 5: invalid client_version|hash; * 6: banned * x: acc state (TODO document me deeper) */ int login_mmo_auth(struct login_session_data* sd, bool isServer) { struct mmo_account acc; int len; char ip[16]; ip2str(session[sd->fd]->client_addr, ip); // DNS Blacklist check if( login_config.use_dnsbl ) { char r_ip[16]; char ip_dnsbl[256]; char* dnsbl_serv; uint8* sin_addr = (uint8*)&session[sd->fd]->client_addr; sprintf(r_ip, "%u.%u.%u.%u", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]); for( dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,",") ) { sprintf(ip_dnsbl, "%s.%s", r_ip, trim(dnsbl_serv)); if( host2ip(ip_dnsbl) ) { ShowInfo("DNSBL: (%s) Blacklisted. User Kicked.\n", r_ip); return 3; } } } //Client Version check if( login_config.check_client_version && sd->version != login_config.client_version_to_connect ){ ShowNotice("Invalid version (account: '%s', auth_vers: '%d', received version: '%d', ip: %s)\n", sd->userid, login_config.client_version_to_connect, sd->version, ip); return 5; } len = strnlen(sd->userid, NAME_LENGTH); // Account creation with _M/_F if( login_config.new_account_flag ) { if( len > 2 && strnlen(sd->passwd, NAME_LENGTH) > 0 && // valid user and password lengths sd->passwdenc == 0 && // unencoded password sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4) ) // _M/_F suffix { int result; // remove the _M/_F suffix len -= 2; sd->userid[len] = '\0'; result = login_mmo_auth_new(sd->userid, sd->passwd, TOUPPER(sd->userid[len+1]), ip); if( result != -1 ) return result;// Failed to make account. [Skotlex]. } } if( !accounts->load_str(accounts, &acc, sd->userid) ) { ShowNotice("Unknown account (account: %s, received pass: %s, ip: %s)\n", sd->userid, sd->passwd, ip); return 0; // 0 = Unregistered ID } if( !login_check_password(sd->md5key, sd->passwdenc, sd->passwd, acc.pass) ) { ShowNotice("Invalid password (account: '%s', pass: '******', received pass: '******', ip: %s)\n", sd->userid, acc.pass, sd->passwd, ip); return 1; // 1 = Incorrect Password } if( acc.expiration_time != 0 && acc.expiration_time < time(NULL) ) { ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip); return 2; // 2 = This ID is expired } if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) { char tmpstr[24]; timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format); ShowNotice("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)\n", sd->userid, sd->passwd, tmpstr, ip); return 6; // 6 = Your are Prohibited to log in until %s } if( acc.state != 0 ) { ShowNotice("Connection refused (account: %s, pass: %s, state: %d, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); return acc.state - 1; } if( login_config.client_hash_check && !isServer ) { struct client_hash_node *node = NULL; bool match = false; for( node = login_config.client_hash_nodes; node; node = node->next ) { if( acc.group_id < node->group_id ) continue; if( *node->hash == '\0' // Allowed to login without hash || (sd->has_client_hash && memcmp(node->hash, sd->client_hash, 16) == 0 ) // Correct hash ) { match = true; break; } } if( !match ) { char smd5[33]; int i; if( !sd->has_client_hash ) { ShowNotice("Client didn't send client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); return 5; } for( i = 0; i < 16; i++ ) sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]); ShowNotice("Invalid client hash (account: %s, pass: %s, sent md5: %d, ip: %s)\n", sd->userid, sd->passwd, smd5, ip); return 5; } } ShowNotice("Authentication accepted (account: %s, id: %d, ip: %s)\n", sd->userid, acc.account_id, ip); // update session data sd->account_id = acc.account_id; sd->login_id1 = rnd() + 1; sd->login_id2 = rnd() + 1; safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin)); sd->sex = acc.sex; sd->group_id = acc.group_id; // update account data timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S"); safestrncpy(acc.last_ip, ip, sizeof(acc.last_ip)); acc.unban_time = 0; acc.logincount++; accounts->save(accounts, &acc); if( sd->sex != 'S' && sd->account_id < START_ACCOUNT_NUM ) ShowWarning("Account %s has account id %d! Account IDs must be over %d to work properly!\n", sd->userid, sd->account_id, START_ACCOUNT_NUM); return -1; // account OK }
static int netlink_msg_handler(struct nl_msg *msg, void *arg) { struct nlmsghdr *hdr; struct tcmsg *tcm; struct nlattr *attrs[TCA_MAX+1]; struct nlattr *stat_attrs[TCA_STATS_MAX+1]; struct qdisc_handler *h; char qdisc[IFNAMSIZ] = {0}; int qdisc_l = 0; char ifname[IFNAMSIZ] = {0}; int ifname_l = 0; struct timeval current_time = {0}; double time; char *ret = NULL; struct gnet_stats_basic *sb; struct gnet_stats_queue *q; struct options *opt = arg; struct recordset rset = {0}; hdr = nlmsg_hdr(msg); tcm = nlmsg_data(hdr); if(!has_iface(opt, tcm->tcm_ifindex)) return NL_SKIP; if((ret = rtnl_link_i2name(opt->cache, tcm->tcm_ifindex, ifname, IFNAMSIZ)) == NULL) return NL_SKIP; // No length checking in netlink library. if((ifname_l = 1 + strnlen(ifname, IFNAMSIZ)) >= IFNAMSIZ) { ifname[IFNAMSIZ-1] = '\0'; ifname_l = IFNAMSIZ; } gettimeofday(¤t_time, NULL); time = (double)current_time.tv_usec / 1000000 + (double) current_time.tv_sec; add_record_double(&rset, "time", sizeof("time"), time); add_record_str(&rset, "iface", sizeof("iface"), ifname, ifname_l); nlmsg_parse(hdr, sizeof(*tcm), attrs, TCA_MAX, tca_policy); if(attrs[TCA_KIND]) { qdisc_l = nla_len(attrs[TCA_KIND]); memcpy(qdisc, nla_get_string(attrs[TCA_KIND]), qdisc_l); add_record_str(&rset, "qdisc", sizeof("qdisc"), qdisc, qdisc_l); } add_record_hex(&rset, "handle", sizeof("handle"), tcm->tcm_handle >> 16); if(attrs[TCA_STATS2]) { nla_parse_nested(stat_attrs, TCA_STATS_MAX, attrs[TCA_STATS2], tca_stats_policy); if(stat_attrs[TCA_STATS_BASIC]) { sb = nla_data(stat_attrs[TCA_STATS_BASIC]); add_record_uint(&rset, "bytes", sizeof("bytes"), sb->bytes); add_record_uint(&rset, "packets", sizeof("packets"), sb->packets); } if(stat_attrs[TCA_STATS_QUEUE]) { q = nla_data(stat_attrs[TCA_STATS_QUEUE]); add_record_uint(&rset, "drops", sizeof("drops"), q->drops); add_record_uint(&rset, "qlen", sizeof("qlen"), q->qlen); add_record_uint(&rset, "backlog", sizeof("backlog"), q->backlog); add_record_uint(&rset, "overlimits", sizeof("overlimits"), q->overlimits); add_record_uint(&rset, "requeues", sizeof("requeues"), q->requeues); } if(stat_attrs[TCA_STATS_APP]) { h = find_qdisc_handler(qdisc); if(h) h->parse_stats(stat_attrs[TCA_STATS_APP], &rset); } } opt->formatter->format(opt->formatter, &rset); clear_records(&rset); if(!opt->run_length || current_time.tv_sec < opt->start_time.tv_sec + opt->run_length) return NL_OK; else return NL_STOP; }
int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO * pfindData, struct super_block *sb, int xid) { int rc = 0; struct cifsTconInfo *pTcon; struct inode *inode; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; char *buf = NULL; pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s ", search_path)); if((pfindData == NULL) && (*pinode != NULL)) { if(CIFS_I(*pinode)->clientCanCacheRead) { cFYI(1,("No need to revalidate inode sizes on cached file ")); return rc; } } /* if file info not passed in then get it from server */ if(pfindData == NULL) { buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, cifs_sb->local_nls); } /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ if (rc) { if (rc == -EREMOTE) { tmp_path = kmalloc(strnlen (pTcon->treeName, MAX_TREE_SIZE + 1) + strnlen(search_path, MAX_PATHCONF) + 1, GFP_KERNEL); if (tmp_path == NULL) { if(buf) kfree(buf); return -ENOMEM; } strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); strncat(tmp_path, search_path, MAX_PATHCONF); rc = connect_to_dfs_path(xid, pTcon->ses, /* treename + */ tmp_path, cifs_sb->local_nls); kfree(tmp_path); /* BB fix up inode etc. */ } else if (rc) { if(buf) kfree(buf); return rc; } } else { struct cifsInodeInfo *cifsInfo; /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); if(*pinode == NULL) return -ENOMEM; insert_inode_hash(*pinode); } inode = *pinode; cifsInfo = CIFS_I(inode); pfindData->Attributes = le32_to_cpu(pfindData->Attributes); cifsInfo->cifsAttrs = pfindData->Attributes; cFYI(1, (" Old time %ld ", cifsInfo->time)); cifsInfo->time = jiffies; cFYI(1, (" New time %ld ", cifsInfo->time)); /* blksize needs to be multiple of two. So safer to default to blksize and blkbits set in superblock so 2**blkbits and blksize will match */ /* inode->i_blksize = (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ /* Linux can not store file creation time unfortunately so we ignore it */ inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); inode->i_mtime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cFYI(0, (" Attributes came in as 0x%x ", pfindData->Attributes)); /* set default mode. will override for dirs below */ if(atomic_read(&cifsInfo->inUse) == 0) /* new inode, can safely set these fields */ inode->i_mode = cifs_sb->mnt_file_mode; if (pfindData->Attributes & ATTR_REPARSE) { /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */ inode->i_mode |= S_IFLNK; } else if (pfindData->Attributes & ATTR_DIRECTORY) { /* override default perms since we do not do byte range locking on dirs */ inode->i_mode = cifs_sb->mnt_dir_mode; inode->i_mode |= S_IFDIR; } else { inode->i_mode |= S_IFREG; /* treat the dos attribute of read-only as read-only mode e.g. 555 */ if(cifsInfo->cifsAttrs & ATTR_READONLY) inode->i_mode &= ~(S_IWUGO); /* BB add code here - validate if device or weird share or device type? */ } if(is_size_safe_to_change(cifsInfo)) { /* can not safely change the file size here if the client is writing to it due to potential races */ i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); /* 512 bytes (2**9) is the fake blocksize that must be used */ /* for this calculation */ inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9; } pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize); inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); /* BB fill in uid and gid here? with help from winbind? or retrieve from NTFS stream extended attribute */ if(atomic_read(&cifsInfo->inUse) == 0) { inode->i_uid = cifs_sb->mnt_uid; inode->i_gid = cifs_sb->mnt_gid; /* set so we do not keep refreshing these fields with bad data after user has changed them in memory */ atomic_set(&cifsInfo->inUse,1); } if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; inode->i_fop = &cifs_file_ops; inode->i_data.a_ops = &cifs_addr_ops; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode ")); inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } else if (S_ISLNK(inode->i_mode)) { cFYI(1, (" Symbolic Link inode ")); inode->i_op = &cifs_symlink_inode_ops; } else { init_special_inode(inode, inode->i_mode, inode->i_rdev); } } if(buf) kfree(buf); return rc; }
char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char *debuginfo_dirs) { INITIALIZE_LIBABRT(); struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) return NULL; char *executable = dd_load_text(dd, FILENAME_EXECUTABLE); dd_close(dd); /* Let user know what's going on */ log(_("Generating backtrace")); unsigned i = 0; char *args[25]; args[i++] = (char*)"gdb"; args[i++] = (char*)"-batch"; struct strbuf *set_debug_file_directory = strbuf_new(); unsigned auto_load_base_index = 0; if(debuginfo_dirs == NULL) { // set non-existent debug file directory to prevent resolving // function names - we need offsets for core backtrace. strbuf_append_str(set_debug_file_directory, "set debug-file-directory /"); } else { strbuf_append_str(set_debug_file_directory, "set debug-file-directory /usr/lib/debug"); struct strbuf *debug_directories = strbuf_new(); const char *p = debuginfo_dirs; while (1) { while (*p == ':') p++; if (*p == '\0') break; const char *colon_or_nul = strchrnul(p, ':'); strbuf_append_strf(debug_directories, "%s%.*s/usr/lib/debug", (debug_directories->len == 0 ? "" : ":"), (int)(colon_or_nul - p), p); p = colon_or_nul; } strbuf_append_strf(set_debug_file_directory, ":%s", debug_directories->buf); args[i++] = (char*)"-iex"; auto_load_base_index = i; args[i++] = xasprintf("add-auto-load-safe-path %s", debug_directories->buf); args[i++] = (char*)"-iex"; args[i++] = xasprintf("add-auto-load-scripts-directory %s", debug_directories->buf); strbuf_free(debug_directories); } args[i++] = (char*)"-ex"; const unsigned debug_dir_cmd_index = i++; args[debug_dir_cmd_index] = strbuf_free_nobuf(set_debug_file_directory); /* "file BINARY_FILE" is needed, without it gdb cannot properly * unwind the stack. Currently the unwind information is located * in .eh_frame which is stored only in binary, not in coredump * or debuginfo. * * Fedora GDB does not strictly need it, it will find the binary * by its build-id. But for binaries either without build-id * (= built on non-Fedora GCC) or which do not have * their debuginfo rpm installed gdb would not find BINARY_FILE * so it is still makes sense to supply "file BINARY_FILE". * * Unfortunately, "file BINARY_FILE" doesn't work well if BINARY_FILE * was deleted (as often happens during system updates): * gdb uses specified BINARY_FILE * even if it is completely unrelated to the coredump. * See https://bugzilla.redhat.com/show_bug.cgi?id=525721 * * TODO: check mtimes on COREFILE and BINARY_FILE and not supply * BINARY_FILE if it is newer (to at least avoid gdb complaining). */ args[i++] = (char*)"-ex"; const unsigned file_cmd_index = i++; args[file_cmd_index] = xasprintf("file %s", executable); free(executable); args[i++] = (char*)"-ex"; const unsigned core_cmd_index = i++; args[core_cmd_index] = xasprintf("core-file %s/"FILENAME_COREDUMP, dump_dir_name); args[i++] = (char*)"-ex"; const unsigned bt_cmd_index = i++; /*args[9] = ... see below */ args[i++] = (char*)"-ex"; args[i++] = (char*)"info sharedlib"; /* glibc's abort() stores its message in __abort_msg variable */ args[i++] = (char*)"-ex"; args[i++] = (char*)"print (char*)__abort_msg"; args[i++] = (char*)"-ex"; args[i++] = (char*)"print (char*)__glib_assert_msg"; args[i++] = (char*)"-ex"; args[i++] = (char*)"info all-registers"; args[i++] = (char*)"-ex"; const unsigned dis_cmd_index = i++; args[dis_cmd_index] = (char*)"disassemble"; args[i++] = NULL; /* Get the backtrace, but try to cap its size */ /* Limit bt depth. With no limit, gdb sometimes OOMs the machine */ unsigned bt_depth = 1024; const char *thread_apply_all = "thread apply all -ascending"; const char *full = " full"; char *bt = NULL; while (1) { args[bt_cmd_index] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full); bt = exec_vp(args, /*redirect_stderr:*/ 1, timeout_sec, NULL); free(args[bt_cmd_index]); if ((bt && strnlen(bt, 256*1024) < 256*1024) || bt_depth <= 32) { break; } bt_depth /= 2; if (bt) log("Backtrace is too big (%u bytes), reducing depth to %u", (unsigned)strlen(bt), bt_depth); else /* (NB: in fact, current impl. of exec_vp() never returns NULL) */ log("Failed to generate backtrace, reducing depth to %u", bt_depth); free(bt); /* Replace -ex disassemble (which disasms entire function $pc points to) * to a version which analyzes limited, small patch of code around $pc. * (Users reported a case where bare "disassemble" attempted to process * entire .bss). * TODO: what if "$pc-N" underflows? in my test, this happens: * Dump of assembler code from 0xfffffffffffffff0 to 0x30: * End of assembler dump. * (IOW: "empty" dump) */ args[dis_cmd_index] = (char*)"disassemble $pc-20, $pc+64"; if (bt_depth <= 64 && thread_apply_all[0] != '\0') { /* This program likely has gazillion threads, dont try to bt them all */ bt_depth = 128; thread_apply_all = ""; } if (bt_depth <= 64 && full[0] != '\0') { /* Looks like there are gigantic local structures or arrays, disable "full" bt */ bt_depth = 128; full = ""; } } if (auto_load_base_index > 0) { free(args[auto_load_base_index]); free(args[auto_load_base_index + 2]); } free(args[debug_dir_cmd_index]); free(args[file_cmd_index]); free(args[core_cmd_index]); return bt; }
int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, struct super_block *sb,int xid) { int rc = 0; FILE_UNIX_BASIC_INFO findData; struct cifsTconInfo *pTcon; struct inode *inode; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; pTcon = cifs_sb->tcon; cFYI(1, (" Getting info on %s ", search_path)); /* we could have done a find first instead but this returns more info */ rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, cifs_sb->local_nls); /* dump_mem("\nUnixQPathInfo return data", &findData, sizeof(findData)); */ if (rc) { if (rc == -EREMOTE) { tmp_path = kmalloc(strnlen (pTcon->treeName, MAX_TREE_SIZE + 1) + strnlen(search_path, MAX_PATHCONF) + 1, GFP_KERNEL); if (tmp_path == NULL) { return -ENOMEM; } /* have to skip first of the double backslash of UNC name */ strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); strncat(tmp_path, search_path, MAX_PATHCONF); rc = connect_to_dfs_path(xid, pTcon->ses, /* treename + */ tmp_path, cifs_sb->local_nls); kfree(tmp_path); /* BB fix up inode etc. */ } else if (rc) { return rc; } } else { struct cifsInodeInfo *cifsInfo; /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); if(*pinode == NULL) return -ENOMEM; insert_inode_hash(*pinode); } inode = *pinode; cifsInfo = CIFS_I(inode); cFYI(1, (" Old time %ld ", cifsInfo->time)); cifsInfo->time = jiffies; cFYI(1, (" New time %ld ", cifsInfo->time)); atomic_set(&cifsInfo->inUse,1); /* ok to set on every refresh of inode */ inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); inode->i_mtime = cifs_NTtimeToUnix(le64_to_cpu (findData.LastModificationTime)); inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); inode->i_mode = le64_to_cpu(findData.Permissions); findData.Type = le32_to_cpu(findData.Type); if (findData.Type == UNIX_FILE) { inode->i_mode |= S_IFREG; } else if (findData.Type == UNIX_SYMLINK) { inode->i_mode |= S_IFLNK; } else if (findData.Type == UNIX_DIR) { inode->i_mode |= S_IFDIR; } else if (findData.Type == UNIX_CHARDEV) { inode->i_mode |= S_IFCHR; inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), le64_to_cpu(findData.DevMinor) & MINORMASK); } else if (findData.Type == UNIX_BLOCKDEV) { inode->i_mode |= S_IFBLK; inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), le64_to_cpu(findData.DevMinor) & MINORMASK); } else if (findData.Type == UNIX_FIFO) { inode->i_mode |= S_IFIFO; } else if (findData.Type == UNIX_SOCKET) { inode->i_mode |= S_IFSOCK; } inode->i_uid = le64_to_cpu(findData.Uid); inode->i_gid = le64_to_cpu(findData.Gid); inode->i_nlink = le64_to_cpu(findData.Nlinks); findData.NumOfBytes = le64_to_cpu(findData.NumOfBytes); findData.EndOfFile = le64_to_cpu(findData.EndOfFile); if(is_size_safe_to_change(cifsInfo)) { /* can not safely change the file size here if the client is writing to it due to potential races */ i_size_write(inode,findData.EndOfFile); /* blksize needs to be multiple of two. So safer to default to blksize and blkbits set in superblock so 2**blkbits and blksize will match */ /* inode->i_blksize = (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ /* This seems incredibly stupid but it turns out that i_blocks is not related to (i_size / i_blksize), instead a size of 512 is required to be used for calculating num blocks */ /* inode->i_blocks = (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;*/ /* 512 bytes (2**9) is the fake blocksize that must be used */ /* for this calculation */ inode->i_blocks = (512 - 1 + findData.NumOfBytes) >> 9; } if (findData.NumOfBytes < findData.EndOfFile) cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file ")); cFYI(1, ("Size %ld and blocks %ld ", (unsigned long) inode->i_size, inode->i_blocks)); if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; inode->i_fop = &cifs_file_ops; inode->i_data.a_ops = &cifs_addr_ops; } else if (S_ISDIR(inode->i_mode)) { cFYI(1, (" Directory inode")); inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } else if (S_ISLNK(inode->i_mode)) { cFYI(1, (" Symbolic Link inode ")); inode->i_op = &cifs_symlink_inode_ops; /* tmp_inode->i_fop = *//* do not need to set to anything */ } else { cFYI(1, (" Init special inode ")); init_special_inode(inode, inode->i_mode, inode->i_rdev); } } return rc; }
FILE * fmemopen (void *buf, size_t len, const char *mode) { cookie_io_functions_t iof; fmemopen_cookie_t *c; if (__builtin_expect (len == 0, 0)) { einval: __set_errno (EINVAL); return NULL; } c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t)); if (c == NULL) return NULL; c->mybuffer = (buf == NULL); if (c->mybuffer) { c->buffer = (char *) malloc (len); if (c->buffer == NULL) { free (c); return NULL; } c->buffer[0] = '\0'; c->maxpos = 0; } else { if (__builtin_expect ((uintptr_t) len > -(uintptr_t) buf, 0)) { free (c); goto einval; } c->buffer = buf; if (mode[0] == 'w') c->buffer[0] = '\0'; c->maxpos = strnlen (c->buffer, len); } c->size = len; if (mode[0] == 'a') c->pos = c->maxpos; else c->pos = 0; c->binmode = mode[0] != '\0' && mode[1] == 'b'; iof.read = fmemopen_read; iof.write = fmemopen_write; iof.seek = fmemopen_seek; iof.close = fmemopen_close; return _IO_fopencookie (c, mode, iof); }
int main(int argc, char* argv[]){ int rv; int inputFD; int outputFD; char inputFilename[MAXFILENAMELENGTH]; char outputFilename[MAXFILENAMELENGTH]; char outputFilenameBase[MAXFILENAMELENGTH]; ssize_t transfersize = 0; ssize_t blocksize = 0; char* transferBuffer = NULL; ssize_t buffersize; ssize_t bytesRead = 0; ssize_t totalBytesRead = 0; int totalReads = 0; ssize_t bytesWritten = 0; ssize_t totalBytesWritten = 0; int totalWrites = 0; int inputFileResets = 0; int processes; transfersize = DEFAULT_TRANSFERSIZE; blocksize = DEFAULT_BLOCKSIZE; /* Set default number of processes */ if(argc < 2){ processes = 1; } if(argc > 1){ processes = atol(argv[1]); if(processes < 1){ fprintf(stderr, "Bad number of processes\n"); exit(EXIT_FAILURE); } } /* Set supplied input filename or default if not supplied */ if(strnlen(DEFAULT_INPUTFILENAME, MAXFILENAMELENGTH) >= MAXFILENAMELENGTH){ fprintf(stderr, "Default input filename too long\n"); exit(EXIT_FAILURE); } strncpy(inputFilename, DEFAULT_INPUTFILENAME, MAXFILENAMELENGTH); /* Set supplied output filename base or default if not supplied */ if(strnlen(DEFAULT_OUTPUTFILENAMEBASE, MAXFILENAMELENGTH) >= MAXFILENAMELENGTH){ fprintf(stderr, "Default output filename base too long\n"); exit(EXIT_FAILURE); } strncpy(outputFilenameBase, DEFAULT_OUTPUTFILENAMEBASE, MAXFILENAMELENGTH); /* Confirm blocksize is multiple of and less than transfersize*/ if(blocksize > transfersize){ fprintf(stderr, "blocksize can not exceed transfersize\n"); exit(EXIT_FAILURE); } if(transfersize % blocksize){ fprintf(stderr, "blocksize must be multiple of transfersize\n"); exit(EXIT_FAILURE); } int pid = forkMe(processes); if(pid != 0){ /* Allocate buffer space */ buffersize = blocksize; if(!(transferBuffer = malloc(buffersize*sizeof(*transferBuffer)))){ perror("Failed to allocate transfer buffer"); exit(EXIT_FAILURE); } /* Open Input File Descriptor in Read Only mode */ if((inputFD = open(inputFilename, O_RDONLY | O_SYNC)) < 0){ perror("Failed to open input file"); exit(EXIT_FAILURE); } /* Open Output File Descriptor in Write Only mode with standard permissions*/ rv = snprintf(outputFilename, MAXFILENAMELENGTH, "%s-%d", outputFilenameBase, getpid()); if(rv > MAXFILENAMELENGTH){ fprintf(stderr, "Output filenmae length exceeds limit of %d characters.\n", MAXFILENAMELENGTH); exit(EXIT_FAILURE); } else if(rv < 0){ perror("Failed to generate output filename"); exit(EXIT_FAILURE); } if((outputFD = open(outputFilename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)) < 0){ perror("Failed to open output file"); exit(EXIT_FAILURE); } /* Print Status */ fprintf(stdout, "Reading from %s and writing to %s\n", inputFilename, outputFilename); /* Read from input file and write to output file*/ do{ /* Read transfersize bytes from input file*/ bytesRead = read(inputFD, transferBuffer, buffersize); if(bytesRead < 0){ perror("Error reading input file"); exit(EXIT_FAILURE); } else{ totalBytesRead += bytesRead; totalReads++; } /* If all bytes were read, write to output file*/ if(bytesRead == blocksize){ bytesWritten = write(outputFD, transferBuffer, bytesRead); if(bytesWritten < 0){ perror("Error writing output file"); exit(EXIT_FAILURE); } else{ totalBytesWritten += bytesWritten; totalWrites++; } } /* Otherwise assume we have reached the end of the input file and reset */ else{ if(lseek(inputFD, 0, SEEK_SET)){ perror("Error resetting to beginning of file"); exit(EXIT_FAILURE); } inputFileResets++; } }while(totalBytesWritten < transfersize); /* Output some possibly helpfull info to make it seem like we were doing stuff */ fprintf(stdout, "Read: %zd bytes in %d reads\n", totalBytesRead, totalReads); fprintf(stdout, "Written: %zd bytes in %d writes\n", totalBytesWritten, totalWrites); fprintf(stdout, "Read input file in %d pass%s\n", (inputFileResets + 1), (inputFileResets ? "es" : "")); fprintf(stdout, "Processed %zd bytes in blocks of %zd bytes\n", transfersize, blocksize); /* Free Buffer */ free(transferBuffer); /* Close Output File Descriptor */ if(close(outputFD)){ perror("Failed to close output file"); exit(EXIT_FAILURE); } /* Close Input File Descriptor */ if(close(inputFD)){ perror("Failed to close input file"); exit(EXIT_FAILURE); } } return EXIT_SUCCESS; }
int socks5_connect (BIO *b) { unsigned char buf[NI_MAXHOST + 16]; int r; struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; uint16_t port_n = htons (ctx->port); size_t sz = 0; /* the length for SOCKS addresses is only one byte. */ if (strnlen (ctx->host, UINT8_MAX + 1) == UINT8_MAX + 1) return 0; verb ("V: proxy5: connecting %s:%d", ctx->host, ctx->port); /* * Hello packet layout: * 1b: Version * 1b: auth methods * nb: method types * * We support only one method (no auth, 0x00). Others listed in RFC * 1928. */ buf[0] = 0x05; buf[1] = 0x01; buf[2] = 0x00; r = BIO_write (b->next_bio, buf, 3); if (r != 3) return 0; r = BIO_read (b->next_bio, buf, 2); if (r != 2) return 0; if (buf[0] != 0x05 || buf[1] != 0x00) { verb ("V: proxy5: auth error %02x %02x", buf[0], buf[1]); return 0; } /* * Connect packet layout: * 1b: version * 1b: command (0x01 is connect) * 1b: reserved, 0x00 * 1b: addr type (0x03 is domain name) * nb: addr len (1b) + addr bytes, no null termination * 2b: port, network byte order */ buf[0] = 0x05; buf[1] = 0x01; buf[2] = 0x00; buf[3] = 0x03; buf[4] = strlen (ctx->host); sz += 5; memcpy (buf + 5, ctx->host, strlen (ctx->host)); sz += strlen (ctx->host); memcpy (buf + sz, &port_n, sizeof (port_n)); sz += sizeof (port_n); r = BIO_write (b->next_bio, buf, sz); if ( -1 == r ) return -1; if ( (size_t) r != sz) return 0; /* * Server's response: * 1b: version * 1b: status (0x00 is okay) * 1b: reserved, 0x00 * 1b: addr type (0x03 is domain name, 0x01 ipv4) * nb: addr len (1b) + addr bytes, no null termination * 2b: port, network byte order */ /* grab up through the addr type */ r = BIO_read (b->next_bio, buf, 4); if ( -1 == r ) return -1; if (r != 4) return 0; if (buf[0] != 0x05 || buf[1] != 0x00) { verb ("V: proxy5: connect error %02x %02x", buf[0], buf[1]); return 0; } if (buf[3] == 0x03) { unsigned int len; r = BIO_read (b->next_bio, buf + 4, 1); if (r != 1) return 0; /* host (buf[4] bytes) + port (2 bytes) */ len = buf[4] + 2; while (len) { r = BIO_read (b->next_bio, buf + 5, min (len, sizeof (buf))); if (r <= 0) return 0; len -= min (len, r); } } else if (buf[3] == 0x01) { /* 4 bytes ipv4 addr, 2 bytes port */ r = BIO_read (b->next_bio, buf + 4, 6); if (r != 6) return 0; } verb ("V: proxy5: connected"); ctx->connected = 1; return 1; }
void do_work(int ac, char **av) { int serv_sock, clnt_sock; int strcnt, loop; int epfd, event_cnt; char buf[BUF_SIZE], respond[BUF_SIZE]; socklen_t adrsz = sizeof(struct sockaddr); struct sockaddr serv_adr, clnt_adr; struct epoll_event *ep_events, event; if(2 != ac){ printf("Usage: %s <port>\n", av[0]); exit(1); } serv_sock = init_sock((struct sockaddr_in*)&serv_adr, NULL, atoi(av[1])); return_if_fail(-1 != serv_sock); return_if_fail(-1 != bind(serv_sock, &serv_adr, adrsz)); return_if_fail(-1 != listen(serv_sock, 5)); epfd = epoll_create(EPOLL_SIZE); ep_events = calloc(sizeof(struct epoll_event), EPOLL_SIZE); event.events = EPOLLIN; event.data.fd = serv_sock; epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event); while(RUN_FLAG){ event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1); if(-1 == event_cnt){ break; } fputs("event_wait\n", stdout); for(loop = 0; loop < event_cnt; loop++){ //Get new client if(ep_events[loop].data.fd == serv_sock){ clnt_sock = accept(serv_sock, &clnt_adr, &adrsz); event.events = EPOLLIN; event.data.fd = clnt_sock; #ifdef UPDATE strcpy(respond, "ALBERT SAY HELO TO YOU:\n"); write(clnt_sock, respond, strlen(respond)); #endif epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); }else{ strcnt = read(ep_events[loop].data.fd, buf, BUF_SIZE); printf("read %d bytes\n", strcnt); write(1, buf, strcnt); if(0 == strcnt || !strncmp("@exit", buf, 5)){ write(ep_events[loop].data.fd, "Bye\n", 4); epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[loop].data.fd, NULL); close(ep_events[loop].data.fd); }else{ #ifdef UPDATE sprintf(respond, "%s[%d bytes] %s", ALBERT, strcnt, buf); strcnt = strnlen(respond, BUF_SIZE); write(ep_events[loop].data.fd, respond, strcnt); #else write(ep_events[loop].data.fd, buf, strcnt); #endif //write(1, respond, strcnt); } } }//end for }//end while close(serv_sock); close(epfd); }
static void execute_command(const char buffer[BUF_SIZE]) { int type; int buffer_len; int start = -1, end = -1; char buf[128]; char command[64]; const char *p = NULL; buffer_len = strnlen(buffer, BUF_SIZE); /* Figre out where command name is located */ for (int i = 0; i < buffer_len + 1; i++) { if (start == -1) { if (buffer[i] == ' ') continue; start = i; continue; } else if (end == -1) { if (buffer[i] != ' ' && buffer[i] != 0) continue; end = i; break; } } if (start == -1 || end == -1) { printf("malformed command.\n"); return; } strlcpy(command, buffer + start, end - start + 1); p = command; if (stat(command, &type, NULL) < 0) { int len; /* FIXME: We use a hard-coded path of just / */ strlcpy(buf, "/", 16); strlcpy(buf + 1, command, strnlen(command, 64) + 1); if (stat(buf, &type, NULL) < 0) { printf("%s: no such file or directory\n", command); return; } p = buf; } if (type != TYPE_DATA) { printf("%s: not a file\n", command); return; } if (fork() == 0) { char argv_buf[256]; if (end == buffer_len) argv_buf[0] = 0; else strlcpy(argv_buf, buffer + end + 1, 256); if (execve(p, argv_buf) < 0) { printf("sh: error: could not start '%s'\n", p); exit(-1); } } wait(NULL); }
// Runs through all automops entries and dumps some basic info // Returns the number of used protocols // int automops_dump_all(struct automops* list) { struct automops *head = list; struct automops *cur = list; struct fields *f=NULL; int anzmops=0, used=0; char str[64], ft[32]; uint32_t SA=0, DA=0; uint8_t *x, *y; char bits_on[18], bits_off[18]; int i=0, j=0; do { if (cur->used==-1) { fprintf(stderr, "AUTOMOPS: Initial element\n"); if ((cur->next==cur)&&(cur->prev==cur)) fprintf(stderr, " No other elements found.\n"); break; } if (cur->used>0) used++; anzmops++; SA=ntohl(cur->SA); x = (uint8_t*) &SA; DA=ntohl(cur->DA); y = (uint8_t*) &DA; char2bits(cur->layers_on, bits_on); char2bits(cur->layers_off, bits_off); fprintf(stderr, "Protocol %i: %s -- %s\n" " Layercodes: X T U I M Q S E\n" " requires %s (0x%02x)\n" " conflicts %s (0x%02x)\n" " L2: EtherType=%04x, sa=%02x:%02x:%02x:%02x:%02x:%02x, da=%02x:%02x:%02x:%02x:%02x:%02x\n" , anzmops, cur->name, cur->desc, bits_on, cur->layers_on, bits_off, cur->layers_off, cur->etype, cur->sa[0], cur->sa[1], cur->sa[2], cur->sa[3], cur->sa[4], cur->sa[5], cur->da[0], cur->da[1], cur->da[2], cur->da[3], cur->da[4], cur->da[5]); if (cur->layers_on&MOPS_IP) { fprintf(stderr, " IP: proto=%i, SA=%u.%u.%u.%u, DA=%u.%u.%u.%u\n", cur->proto, *x, *(x+1), *(x+2), *(x+3), *y, *(y+1), *(y+2), *(y+3)); } else { fprintf(stderr, " IP: ---\n"); } // Walk through field data: f=cur->field; j=0; while (f!=NULL) { j++; // count number of fields if (verbose) { i=0; if (f->longdesc!=NULL) { mz_strncpy(str, f->longdesc, 60); if (strnlen(str,60)>=59) i=1; } else { mz_strncpy(str, "-- no long description specified --", 60); } amp_type2str(f->type, ft); fprintf(stderr, " %02i Field [%i] '%s' -- %s\n" " Description: %s%s\n" " Type: %s %s %s (%lu/%lu) {%lu..%lu..%lu} shift: %i; %i chars\n" ,f->i, f->index, f->name, f->shortdesc, str, (i) ? "..." : "", ft, (f->constant) ? "FIXED" : "", (f->valname!=NULL) ? f->valname : "(no value name)" , (long unsigned int) f->tlv_type, (long unsigned int) f->tlv_len, (long unsigned int) f->min, (long unsigned int) f->val, (long unsigned int) f->max, f->leftshift, f->str_s); } f=f->next; } if (verbose==0) fprintf(stderr, " %i fields defined.\n", j); //--------------------------------- cur = cur->next; } while (head != cur); return used; }
static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) { int64_t offset = 0; bool noraid = false; int fd = -1; blkid_probe pr; const char *data; const char *name; int nvals; int i; size_t len; int err = 0; static const struct option options[] = { { "offset", optional_argument, NULL, 'o' }, { "noraid", no_argument, NULL, 'R' }, {} }; for (;;) { int option; option = getopt_long(argc, argv, "oR", options, NULL); if (option == -1) break; switch (option) { case 'o': offset = strtoull(optarg, NULL, 0); break; case 'R': noraid = true; break; } } pr = blkid_new_probe(); if (!pr) return EXIT_FAILURE; blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); if (noraid) blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID); fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC); if (fd < 0) { fprintf(stderr, "error: %s: %m\n", udev_device_get_devnode(dev)); goto out; } err = blkid_probe_set_device(pr, fd, offset, 0); if (err < 0) goto out; log_debug("probe %s %sraid offset=%llu\n", udev_device_get_devnode(dev), noraid ? "no" : "", (unsigned long long) offset); err = probe_superblocks(pr); if (err < 0) goto out; nvals = blkid_probe_numof_values(pr); for (i = 0; i < nvals; i++) { if (blkid_probe_get_value(pr, i, &name, &data, &len)) continue; len = strnlen((char *) data, len); print_property(dev, test, name, (char *) data); } blkid_free_probe(pr); out: if (fd > 0) close(fd); if (err < 0) return EXIT_FAILURE; return EXIT_SUCCESS; }
static PyObject * pyshark_iter(PyObject *self, PyObject *args) { gsize i; char *filename; PyObject *keylistobj; const char *dfilter; char *decode_as = NULL; pyshark_Iter *p; gint ret; /* NB: Automatic sanity checks for 1st, 3rd, and optional 4th argument */ if(!PyArg_ParseTuple(args, "sOs|s", &filename, &keylistobj, &dfilter, &decode_as)) { return NULL; } /* NB: Explicit sanity checks needed for the second argument */ if(!PyList_Check(keylistobj)) { PyErr_SetString(PyExc_TypeError, "Second argument must be a list of wireshark fieldnames"); return NULL; } for(i = 0; i < PyList_Size(keylistobj); i++) { PyObject *fieldnameobj = PyList_GetItem(keylistobj, i); if (!PyString_Check(fieldnameobj)) { PyErr_SetString(PyExc_TypeError, "All items in second argument list must be strings"); return NULL; } } /* NB: See PyObject.ob_type in http://docs.python.org/c-api/typeobj.html for more info */ pyshark_IterType.ob_type = &PyType_Type; //pyshark_Iter; /* NB: look at bottom of http://docs.python.org/c-api/type.html */ ret = PyType_Ready(&pyshark_IterType); if(ret) { return NULL; } /* Create our iterator object */ p = PyObject_New(pyshark_Iter, &pyshark_IterType); if(!p) { return NULL; } /* Initialize all our data structures in the iterator object to 0. This makes it easier to implement deallocation logic for both expected and unexpected cases. */ p->clean = FALSE; p->decode_as = NULL; p->stdata = NULL; p->nwpykeylist = NULL; p->wpykeyhash = NULL; p->asel = FALSE; p->show_empty_fields = FALSE; if(!PyObject_Init((PyObject *)p, &pyshark_IterType)) { Py_DECREF(p); return NULL; } p->stdata = stdata_new(); if(!p->stdata) { Py_DECREF(p); return NULL; } p->wpykeyhash = g_hash_table_new(g_str_hash, g_str_equal); p->nwpykeylist = g_ptr_array_new(); /* Iterate through the Python List and add to either fieldnames OR wfieldnames depending on presence of a '*' in the string */ for(i = 0; i < PyList_Size(keylistobj); i++) { /* NB: we know these are not NULL because of our sanity checks above */ PyObject *keyobj = PyList_GetItem(keylistobj, i); /* Check for wildcard entries, e.g. "*", "ip.*", "eth.*", etc. */ const gchar *key = PyString_AsString(keyobj); gchar *ptr = g_strstr_len(key, strnlen(key, 100), "*"); if(ptr) { /* We have a fieldname with a wildcard in it * * Use pointer arithmetic to figure out the length * TODO: better way to do this, maybe? */ gsize prefix_len = (gsize)ptr - (gsize)key; g_ptr_array_add(p->stdata->wfieldnames, g_strndup(key, prefix_len)); } else { /* * Non-wildcard entry. */ g_ptr_array_add(p->stdata->fieldnames, PyString_AsString(keyobj)); /* On the python-module side of things, keep a list of python objects, one for each non-wildcard fieldname to be processed by sharktools. NB: the index between entries in p->{stdata->fieldnames,nwpykeylist} MUST be the same. */ g_ptr_array_add(p->nwpykeylist, keyobj); /* The above array_add() call doesn't deep copy the fieldname, let's increment the refcount, and decrement it when we cleanup. NB: also used for our copy of the key in p->nwpykeylist */ Py_INCREF(keyobj); } } /* If there is a decode_as string set, add it */ if(decode_as) { dprintf("decode as string added: %s\n", decode_as); ret = sharktools_add_decode_as(decode_as); if(ret == FALSE) { dprintf("%s\n", sharktools_errmsg); PyErr_SetString(PySharkError, sharktools_errmsg); Py_DECREF(p); return NULL; } /* NB: Add to object state; we'll need to remove it later */ p->decode_as = strndup(decode_as, strlen(decode_as)); } /* * Create and initialize sharktools' state */ ret = sharktools_iter_init(p->stdata, filename, strdup(dfilter)); if(ret < 0) { dprintf("%s\n", sharktools_errmsg); PyErr_SetString(PySharkError, sharktools_errmsg); Py_DECREF(p); return NULL; } /* NB: We are dirty */ p->clean = FALSE; return (PyObject *)p; }