atf_error_t atf_fs_mkstemp(atf_fs_path_t *p, int *fdout) { atf_error_t err; char *buf; int fd; if (!check_umask(S_IRWXU, S_IRWXU)) { err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask()); goto out; } err = copy_contents(p, &buf); if (atf_is_error(err)) goto out; err = do_mkstemp(buf, &fd); if (atf_is_error(err)) goto out_buf; replace_contents(p, buf); *fdout = fd; INV(!atf_is_error(err)); out_buf: free(buf); out: return err; }
void DocumentView::save(const unicode& path) { L_DEBUG("Saving file: " + path.encode()); trim_trailing_newlines(); trim_trailing_whitespace(); Glib::ustring text = buffer()->get_text(); if(file_->get_path() == path.encode()) { //FIXME: Use entity tag arguments to make sure that the file //didn't change since the last time we saved file_->replace_contents(std::string(text.c_str()), "", file_etag_); connect_file_monitor(); } else { auto file = Gio::File::create_for_path(path.encode()); if(!os::path::exists(path)) { file->create_file(); } file->replace_contents(text, "", file_etag_); connect_file_monitor(); } buffer()->set_modified(false); apply_settings(guess_mimetype()); //Make sure we update the settings when we've saved the file window_.rebuild_open_list(); run_linters_and_stuff(); }
atf_error_t atf_fs_mkdtemp(atf_fs_path_t *p) { atf_error_t err; char *buf = NULL; if (!check_umask(S_IRWXU, S_IRWXU)) { err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask()); goto out; } err = copy_contents(p, &buf); if (atf_is_error(err)) goto out; err = do_mkdtemp(buf); if (atf_is_error(err)) goto out_buf; replace_contents(p, buf); INV(!atf_is_error(err)); out_buf: free(buf); out: return err; }
/* * Mangle the "Transport:" header: * - Replace all occurences of "client_port=<spec>" * - Handle destination parameter * * In: * ct, ctinfo = conntrack context * skb = packet * tranoff = Transport header offset from TCP data * tranlen = Transport header length (incl. CRLF) * rport_lo = replacement low port (host endian) * rport_hi = replacement high port (host endian) * * Returns packet size difference. * * Assumes that a complete transport header is present, ending with CR or LF */ static int rtsp_mangle_tran(enum ip_conntrack_info ctinfo, struct nf_conntrack_expect* rtp_exp, struct nf_conntrack_expect* rtcp_exp, struct ip_ct_rtsp_expect* prtspexp, struct sk_buff* skb, uint tranoff, uint tranlen) { char* ptcp; char* ptcp_seq; uint tcplen; char* ptran; char rbuf1[16]; /* Replacement buffer (one port) */ uint rbuf1len; /* Replacement len (one port) */ char rbufa[16]; /* Replacement buffer (all ports) */ uint rbufalen; /* Replacement len (all ports) */ u_int32_t newip; u_int16_t loport, hiport; uint off = 0; uint diff; /* Number of bytes we removed */ int diff_len = 0; #define MAX_RTSP_MANGLE_BUFFER 1400 char mangle_buffer[MAX_RTSP_MANGLE_BUFFER]; uint len_old = 0, len_new = 0; struct nf_conn *ct = rtp_exp->master; struct nf_conntrack_tuple *t_rtp, *t_rtcp; char szextaddr[15+1]; uint extaddrlen; int is_stun; #if 1 /* patch ...*/ ptcp = mangle_buffer; memset(ptcp, 0, MAX_RTSP_MANGLE_BUFFER); get_skb_tcpdata(skb, &ptcp_seq, &tcplen); memcpy(mangle_buffer, ptcp_seq, tcplen); #else get_skb_tcpdata(skb, &ptcp, &tcplen); #endif ptran = ptcp+tranoff; if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen || tranlen < 10 || !iseol(ptran[tranlen-1]) || nf_strncasecmp(ptran, "Transport:", 10) != 0) { pr_info("sanity check failed\n"); return 0; } off += 10; SKIP_WSPACE(ptcp+tranoff, tranlen, off); newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; #ifdef CONFIG_NF_NAT_NEEDED rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port; #endif t_rtp = &rtp_exp->tuple; t_rtcp = &rtcp_exp->tuple; t_rtp->dst.u3.ip = newip; t_rtcp->dst.u3.ip = newip; //extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip) // : sprintf(szextaddr, "%pI4", &newip); extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip)) : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip)); pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto")); rbuf1len = rbufalen = 0; switch (prtspexp->pbtype) { case pb_single: for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ { t_rtp->dst.u.udp.port = htons(loport); if (nf_ct_expect_related(rtp_exp) == 0) { printk("using port %hu\n", loport); break; } } if (loport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); rbufalen = sprintf(rbufa, "%hu", loport); } break; case pb_range: for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */ { t_rtp->dst.u.udp.port = htons(loport); if (nf_ct_expect_related(rtp_exp) == 0) { t_rtcp->dst.u.udp.port = htons(loport+1); if (nf_ct_expect_related(rtcp_exp) == 0) { hiport = loport+1; pr_debug("using ports %d-%d\n", loport, loport+1); } else { hiport = 0; } break; } } if (loport != 0 && hiport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport); } break; case pb_discon: for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ { t_rtp->dst.u.udp.port = htons(loport); if (nf_ct_expect_related(rtp_exp) == 0) { pr_debug("using port %hu (1 of 2)\n", loport); break; } } for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */ { t_rtcp->dst.u.udp.port = htons(hiport); if (nf_ct_expect_related(rtcp_exp) == 0) { pr_debug("using port %hu (2 of 2)\n", hiport); break; } } if (loport != 0 && hiport != 0) { rbuf1len = sprintf(rbuf1, "%hu", loport); if (hiport == loport+1) { rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport); } else { rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport); } } break; } if (rbuf1len == 0) { return 0; /* cannot get replacement port(s) */ } /* Transport: tran;field;field=val,tran;field;field=val,... */ while (off < tranlen) { uint saveoff; const char* pparamend; uint nextparamoff; pparamend = memchr(ptran+off, ',', tranlen-off); pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; //nextparamoff = pparamend-ptcp; nextparamoff = pparamend-ptran; /* * We pass over each param twice. On the first pass, we look for a * destination= field. It is handled by the security policy. If it * is present, allowed, and equal to our external address, we assume * that STUN is being used and we leave the client_port= field alone. */ is_stun = 0; saveoff = off; while (off < nextparamoff) { const char* pfieldend; uint nextfieldoff; uint replen; pfieldend = memchr(ptran+off, ';', nextparamoff-off); nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) { if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0) { is_stun = 1; } if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) { off += 12; replen = (pfieldend == NULL) ? nextfieldoff-off : nextfieldoff-off-1; diff = replen - extaddrlen; #if 1 if( replace_contents(ptran+off, replen, szextaddr, extaddrlen, tcplen-off-(ptran-ptcp)) == 0) { // mangle failed, all we can do is bail nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return 0; } tcplen = tcplen + extaddrlen - replen; diff_len = diff_len + extaddrlen - replen; #else if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, off, diff, NULL, 0)) { // mangle failed, all we can do is bail nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return 0; } #endif #if 0 get_skb_tcpdata(skb, &ptcp, &tcplen); #endif ptran = ptcp+tranoff; tranlen -= diff; nextparamoff -= diff; nextfieldoff -= diff; } } off = nextfieldoff; } if (is_stun) { continue; } off = saveoff; while (off < nextparamoff) { const char* pfieldend; uint nextfieldoff; pfieldend = memchr(ptran+off, ';', nextparamoff-off); nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; if (strncmp(ptran+off, "client_port=", 12) == 0) { u_int16_t port; uint numlen; uint origoff; uint origlen; char* rbuf = rbuf1; uint rbuflen = rbuf1len; uint off1; off += 12; off1 = off; origoff = (ptran-ptcp)+off; origlen = 0; numlen = nf_strtou16(ptran+off, &port); off += numlen; origlen += numlen; if (port != prtspexp->loport) { pr_debug("multiple ports found, port %hu ignored\n", port); } else { if (ptran[off] == '-' || ptran[off] == '/') { off++; origlen++; numlen = nf_strtou16(ptran+off, &port); off += numlen; origlen += numlen; rbuf = rbufa; rbuflen = rbufalen; } /* * note we cannot just memcpy() if the sizes are the same. * the mangle function does skb resizing, checks for a * cloned skb, and updates the checksums. * * parameter 4 below is offset from start of tcp data. */ diff = origlen-rbuflen; #if 1 if( replace_contents(ptran+off1, origlen, rbuf, rbuflen, tcplen-off1-(ptran-ptcp)) == 0) { /* mangle failed, all we can do is bail */ nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return 0; } tcplen = tcplen + rbuflen - origlen; diff_len = diff_len + rbuflen - origlen; #else if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, origoff, origlen, rbuf, rbuflen)) { /* mangle failed, all we can do is bail */ nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return 0; } #endif #if 0 get_skb_tcpdata(skb, &ptcp, &tcplen); #endif ptran = ptcp+tranoff; tranlen -= diff; nextparamoff -= diff; nextfieldoff -= diff; } } off = nextfieldoff; } off = nextparamoff; } if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, 0, tcplen-diff_len, mangle_buffer, tcplen)) { /* mangle failed, all we can do is bail */ //DEBUGP(" mangle failed client_port\n"); nf_ct_unexpect_related(rtp_exp); nf_ct_unexpect_related(rtcp_exp); return 0; } return 1; }