예제 #1
0
/**
 * Wiped the given entry
 */
void wipeEntry(direntry_t *entry)
{
	direntry_t longNameEntry;
	int i;
	initializeDirentry(&longNameEntry, entry->Dir);
	for(i=entry->beginSlot; i< entry->endSlot; i++) {
	    int error;
	    longNameEntry.entry=i;
	    dir_read(&longNameEntry, &error);
	    if(error)
		break;
	    longNameEntry.dir.name[0] = (char) DELMARK;
	    dir_write(&longNameEntry);
	}
	entry->dir.name[0] = (char) DELMARK;
	dir_write(entry);
}
예제 #2
0
/*
 * Open the named file for read, create the cluster chain, return the
 * directory structure or NULL on error.
 */
int makeit(char *dosname,
	    char *longname,
	    void *arg0,
	    direntry_t *targetEntry)
{
	Stream_t *Target;
	CreateArg_t *arg = (CreateArg_t *) arg0;
	int fat;
	direntry_t subEntry;	

	/* will it fit? At least one cluster must be free */
	if (!getfreeMinClusters(targetEntry->Dir, 1))
		return -1;
	
	mk_entry(dosname, ATTR_DIR, 1, 0, arg->mtime, &targetEntry->dir);
	Target = OpenFileByDirentry(targetEntry);
	if(!Target){
		fprintf(stderr,"Could not open Target\n");
		return -1;
	}

	/* this allocates the first cluster for our directory */

	initializeDirentry(&subEntry, Target);

	subEntry.entry = 1;
	GET_DATA(targetEntry->Dir, 0, 0, 0, &fat);
	if (fat == fat32RootCluster(targetEntry->Dir)) {
	    fat = 0;
	}
	mk_entry("..         ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
	dir_write(&subEntry);

	FLUSH((Stream_t *) Target);
	subEntry.entry = 0;
	GET_DATA(Target, 0, 0, 0, &fat);
	mk_entry(".          ", ATTR_DIR, fat, 0, arg->mtime, &subEntry.dir);
	dir_write(&subEntry);

	mk_entry(dosname, ATTR_DIR | arg->attr, fat, 0, arg->mtime, 
		 &targetEntry->dir);
	arg->NewDir = Target;
	return 0;
}
예제 #3
0
파일: fs-up.c 프로젝트: dpc/rdup
static gboolean
mk_dir(struct rdup *e, GHashTable * uidhash, GHashTable * gidhash)
{
	struct stat *s;
	struct stat st;
	gchar *parent;

	if (opt_dry)
		return TRUE;

	if (lstat(e->f_name, &st) == 0) {
		if (S_ISDIR(st.st_mode)) {
#if 0
			msgd(__func__, __LINE__,
			     _("Updating current dir `%s\'"), e->f_name);
#endif				/* DEBUG */
			/* some dir is here - update the perms and ownership */
			mk_meta(e, uidhash, gidhash);
			return TRUE;
		}
	}
	/* nothing there */

	if (mkdir(e->f_name, e->f_mode) == -1) {
		if (errno == EACCES) {
			/* make parent dir writable, and try again */
			parent = dir_parent(e->f_name);
#ifdef DEBUG
			msgd(__func__, __LINE__, _("EACCES for `%s\'"), parent);
#endif				/* DEBUG */
			s = dir_write(parent);
			if (!s)
				msgd(__func__, __LINE__,
				     _("Failed to make parent writable"));

			if (mkdir(e->f_name, e->f_mode) == -1) {
				msgd(__func__, __LINE__,
				     _("Failed to create directory `%s\': %s"),
				     e->f_name, strerror(errno));
				dir_restore(parent, s);
				g_free(parent);
				return FALSE;
			}
			dir_restore(parent, s);
			g_free(parent);
		} else {
			msgd(__func__, __LINE__,
			     _("Failed to create directory `%s\': %s"),
			     e->f_name, strerror(errno));
			return FALSE;
		}
	}
	mk_meta(e, uidhash, gidhash);
	return TRUE;
}
예제 #4
0
파일: mattrib.c 프로젝트: Distrotech/mtools
static int attrib_file(direntry_t *entry, MainParam_t *mp)
{
	Arg_t *arg=(Arg_t *) mp->arg;

	if(entry->entry != -3) {
		/* if not root directory, change it */
		entry->dir.attr = (entry->dir.attr & arg->remove) | arg->add;
		dir_write(entry);
	}
	return GOT_ONE;
}
예제 #5
0
static int flush_file(Stream_t *Stream)
{
	DeclareThis(File_t);
	direntry_t *entry = &This->direntry;

	if(isRootDir(Stream)) {
		return 0;
	}

	if(This->FirstAbsCluNr != getStart(entry->Dir, &entry->dir)) {
		set_word(entry->dir.start, This->FirstAbsCluNr & 0xffff);
		set_word(entry->dir.startHi, This->FirstAbsCluNr >> 16);
		dir_write(entry);
	}
예제 #6
0
파일: fs-up.c 프로젝트: dpc/rdup
static gboolean
mk_link(struct rdup *e, char *p, GHashTable * uidhash, GHashTable * gidhash)
{
	struct stat *st;
	gchar *t;
	gchar *parent;

	if (opt_dry)
		return TRUE;

	if (!rm(e->f_name))
		return FALSE;

	/* symlink */
	if (S_ISLNK(e->f_mode)) {
		if (symlink(e->f_target, e->f_name) == -1) {
			if (errno == EACCES) {
				parent = dir_parent(e->f_name);
				st = dir_write(parent);
				if (symlink(e->f_target, e->f_name) == -1) {
					msgd(__func__, __LINE__,
					     _
					     ("Failed to make symlink `%s -> %s\': %s"),
					     e->f_name, e->f_target,
					     strerror(errno));
					dir_restore(parent, st);
					g_free(parent);
					return FALSE;
				}
				dir_restore(parent, st);
				g_free(parent);
			} else {
				msgd(__func__, __LINE__,
				     _
				     ("Failed to make symlink `%s -> %s\': %s"),
				     e->f_name, e->f_target, strerror(errno));
				return FALSE;
			}
		}
		mk_chown(e, uidhash, gidhash);
		return TRUE;
	}

	/* hardlink */
	/* target must also fall in backup dir */
	t = g_strdup_printf("%s%s", p, e->f_target);
	e->f_target = t;
	hlink_list = g_slist_append(hlink_list, entry_dup(e));
	return TRUE;
}
예제 #7
0
파일: fatdir.c 프로젝트: TijmenW/FreeDOS
VOID dir_close(REG f_node_ptr fnp)
{
  /* Test for invalid f_nodes                                     */
  if (fnp == NULL || !(fnp->f_flags & F_DDIR))
    return;

#ifndef IPL
  /* Write out the entry                                          */
  dir_write(fnp);

#endif
  /* Clear buffers after release                                  */
  /* hazard: no error checking! */
  flush_buffers(fnp->f_dpb->dpb_unit);

  /* and release this instance of the fnode                       */
  release_f_node(fnp);
}
예제 #8
0
파일: fatdir.c 프로젝트: TijmenW/FreeDOS
VOID dir_close(REG f_node_ptr fnp)
{
  REG COUNT disk = fnp->f_dpb->dpb_unit;

  /* Test for invalid f_nodes                                     */
  if (fnp == NULL)
    return;

#ifndef IPL
  /* Write out the entry                                          */
  dir_write(fnp);

#endif
  /* Clear buffers after release                                  */
  flush_buffers(disk);

  /* and release this instance of the fnode                       */
  release_f_node(fnp);
}
예제 #9
0
파일: fs-up.c 프로젝트: dpc/rdup
/* Create the remaining hardlinks in the target directory */
gboolean mk_hlink(GSList * h)
{
	struct rdup *e;
	GSList *p;
	struct stat *st;
	gchar *parent;

	if (opt_dry)
		return TRUE;

	for (p = g_slist_nth(h, 0); p; p = p->next) {
		e = (struct rdup *)p->data;
		if (link(e->f_target, e->f_name) == -1) {
			if (errno == EACCES) {
				parent = dir_parent(e->f_name);
				st = dir_write(parent);
				if (link(e->f_target, e->f_name) == -1) {
					msgd(__func__, __LINE__,
					     _
					     ("Failed to create hardlink `%s -> %s\': %s"),
					     e->f_name, e->f_target,
					     strerror(errno));
					dir_restore(parent, st);
					g_free(parent);
					return FALSE;
				}
				dir_restore(parent, st);
				g_free(parent);
				return TRUE;
			} else {
				msgd(__func__, __LINE__,
				     _
				     ("Failed to create hardlink `%s -> %s\': %s"),
				     e->f_name, e->f_target, strerror(errno));
				return FALSE;
			}
		}
		entry_free(e);
	}
	return TRUE;
}
예제 #10
0
파일: fs-up.c 프로젝트: dpc/rdup
static gboolean
mk_dev(struct rdup *e, GHashTable * uidhash, GHashTable * gidhash)
{
	gchar *parent;
	struct stat *st;

	if (opt_dry)
		return TRUE;

	if (!rm(e->f_name))
		return FALSE;

	if (mknod(e->f_name, e->f_mode, e->f_rdev) == -1) {
		if (errno == EACCES) {
			parent = dir_parent(e->f_name);
			st = dir_write(parent);
			if (mknod(e->f_name, e->f_mode, e->f_rdev) == -1) {
				msgd(__func__, __LINE__,
				     _("Failed to make device `%s\': %s"),
				     e->f_name, strerror(errno));
				dir_restore(parent, st);
				g_free(parent);
				return FALSE;
			}
			dir_restore(parent, st);
			g_free(parent);
		} else {
			msgd(__func__, __LINE__,
			     _("Failed to make device `%s\': %s"), e->f_name,
			     strerror(errno));
			return FALSE;
		}
	}
	mk_meta(e, uidhash, gidhash);
	return TRUE;
}
예제 #11
0
파일: fs-up.c 프로젝트: dpc/rdup
static gboolean
mk_reg(FILE * in, struct rdup *e, GHashTable * uidhash, GHashTable * gidhash)
{
	FILE *out = NULL;
	char *buf;
	gchar *parent;
	size_t bytes;
	gboolean ok = TRUE;
	gboolean old_dry = opt_dry;
	struct stat *st;

	/* with opt_dry we can't just return TRUE; as we may
	 * need to suck in the file's content - which is thrown
	 * away in that case */

	if (!e->f_name) {
		/* fake an opt_dry */
		opt_dry = TRUE;
	}

	if (!opt_dry) {
		if (!rm(e->f_name)) {
			opt_dry = old_dry;
			return FALSE;
		}
	}
	if (!opt_dry && !(out = fopen(e->f_name, "w"))) {
		if (errno == EACCES) {
			parent = dir_parent(e->f_name);
			st = dir_write(parent);
			if (!(out = fopen(e->f_name, "w"))) {
				msgd(__func__, __LINE__,
				     _("Failed to open file `%s\': %s"),
				     e->f_name, strerror(errno));
				g_free(parent);
				ok = FALSE;
			}
			dir_restore(parent, st);
			g_free(parent);
		} else {
			msgd(__func__, __LINE__,
			     _("Failed to open file `%s\': %s"), e->f_name,
			     strerror(errno));
			ok = FALSE;
		}
	}

	/* we need to read the input to not upset
	 * the flow into rdup-up, but we are not
	 * creating anything when opt_dry is active
	 */
	buf = g_malloc(BUFSIZE + 1);
	while ((bytes = block_in_header(in)) > 0) {
		if (block_in(in, bytes, buf) == -1) {
			if (out)
				fclose(out);
			opt_dry = old_dry;
			g_free(buf);
			return FALSE;
		}
		if (ok && !opt_dry) {
			if (fwrite(buf, sizeof(char), bytes, out) != bytes) {
				msgd(__func__, __LINE__,
				     _("Write failure `%s\': %s"), e->f_name,
				     strerror(errno));
				if (out)
					fclose(out);
				opt_dry = old_dry;
				g_free(buf);
				return FALSE;
			}
		}
	}
	g_free(buf);
	if (ok && out)
		fclose(out);

	if (ok && !opt_dry)
		mk_meta(e, uidhash, gidhash);

#ifdef DEBUG
	msgd(__func__, __LINE__, "Wrote file `%s\'", e->f_name);
#endif				/* DEBUG */
	opt_dry = old_dry;
	return TRUE;
}
예제 #12
0
static inline clash_action get_slots(Stream_t *Dir,
				     char *dosname, char *longname,
				     struct scan_state *ssp,
				     ClashHandling_t *ch)
{
	int error;
	clash_action ret;
	int match=0;
	direntry_t entry;
	int isprimary;
	int no_overwrite;
	int reason;
	int pessimisticShortRename;

	pessimisticShortRename = (ch->action[0] == NAMEMATCH_AUTORENAME);

	entry.Dir = Dir;
	no_overwrite = 1;
	if((is_reserved(longname,1)) ||
	   longname[strspn(longname,". ")] == '\0'){
		reason = RESERVED;
		isprimary = 1;
	} else if(contains_illegals(longname,long_illegals)) {
		reason = ILLEGALS;
		isprimary = 1;
	} else if(is_reserved(dosname,0)) {
		reason = RESERVED;
		ch->use_longname = 1;
		isprimary = 0;
	} else if(contains_illegals(dosname,short_illegals)) {
		reason = ILLEGALS;
		ch->use_longname = 1;
		isprimary = 0;
	} else {
		reason = EXISTS;
		clear_scan(longname, ch->use_longname, ssp);
		switch (lookupForInsert(Dir, dosname, longname, ssp,
								ch->ignore_entry, 
								ch->source_entry,
								pessimisticShortRename && 
								ch->use_longname)) {
			case -1:
				return NAMEMATCH_ERROR;
				
			case 0:
				return NAMEMATCH_SKIP; 
				/* Single-file error error or skip request */
				
			case 5:
				return NAMEMATCH_GREW;
				/* Grew directory, try again */
				
			case 6:
				return NAMEMATCH_SUCCESS; /* Success */
		}	    
		match = -2;
		if (ssp->longmatch > -1) {
			/* Primary Long Name Match */
#ifdef debug
			fprintf(stderr,
				"Got longmatch=%d for name %s.\n", 
				longmatch, longname);
#endif			
			match = ssp->longmatch;
			isprimary = 1;
		} else if ((ch->use_longname & 1) && (ssp->shortmatch != -1)) {
			/* Secondary Short Name Match */
#ifdef debug
			fprintf(stderr,
				"Got secondary short name match for name %s.\n", 
				longname);
#endif

			match = ssp->shortmatch;
			isprimary = 0;
		} else if (ssp->shortmatch >= 0) {
			/* Primary Short Name Match */
#ifdef debug
			fprintf(stderr,
				"Got primary short name match for name %s.\n", 
				longname);
#endif
			match = ssp->shortmatch;
			isprimary = 1;
		} else 
			return NAMEMATCH_RENAME;

		if(match > -1) {
			entry.entry = match;
			dir_read(&entry, &error);
			if (error)
			    return NAMEMATCH_ERROR;
			/* if we can't overwrite, don't propose it */
			no_overwrite = (match == ch->source || IS_DIR(&entry));
		}
	}
	ret = process_namematch(isprimary ? longname : dosname, longname,
				isprimary, ch, no_overwrite, reason);
	
	if (ret == NAMEMATCH_OVERWRITE && match > -1){
		if((entry.dir.attr & 0x5) &&
		   (ask_confirmation("file is read only, overwrite anyway (y/n) ? ",0,0)))
			return NAMEMATCH_RENAME;
		
		/* Free up the file to be overwritten */
		if(fatFreeWithDirentry(&entry))
			return NAMEMATCH_ERROR;
		
#if 0
		if(isprimary &&
		   match - ssp->match_free + 1 >= ssp->size_needed){
			/* reuse old entry and old short name for overwrite */
			ssp->free_start = match - ssp->size_needed + 1;
			ssp->free_size = ssp->size_needed;
			ssp->slot = match;
			ssp->got_slots = 1;
			strncpy(dosname, dir.name, 3);
			strncpy(dosname + 8, dir.ext, 3);
			return ret;
		} else
#endif
			{
			entry.dir.name[0] = DELMARK;
			dir_write(&entry);
			return NAMEMATCH_RENAME;
		}
	}

	return ret;
}
예제 #13
0
  // TODO: read/write external should use buffer->valid_db_size instead of passing in additional
  // parameters
  void *DiskIOThread::run_thread(void *_thr_info){
    DiskIOThread *diskio = (DiskIOThread *) _thr_info;

    int ret = zmq_socket_monitor(diskio->sock, "inproc://monitor.router_sock", ZMQ_EVENT_CONNECTED | ZMQ_EVENT_ACCEPTED | ZMQ_EVENT_DISCONNECTED);
    if(ret < 0){
      diskio->status = -1;
      return NULL;
    }

    zmq::socket_t monitor_sock(*diskio->zmq_ctx, ZMQ_PAIR);
    try{
      monitor_sock.connect("inproc://monitor.router_sock");
    }catch(zmq::error_t &e){
      std::cout << "monitor socket create failed" << std::endl;
      return NULL;
    }

    zmq::pollitem_t pollitems[3];
    pollitems[0].socket = diskio->sock;
    pollitems[0].events = ZMQ_POLLIN;
    pollitems[1].socket = monitor_sock;
    pollitems[1].events = ZMQ_POLLIN;
    pollitems[2].socket = diskio->cancel_sock;
    pollitems[2].events = ZMQ_POLLIN;

    while(true){
      try {
        zmq::poll(pollitems, 3);
      }catch(...){
        std::cout << "error from poll!" << std::endl;
        return NULL;
      }

      if(pollitems[2].revents){
        int32_t cid;
        boost::shared_array<uint8_t> data;
        int32_t len = recv_msg(diskio->cancel_sock, cid, data);
        if(len < 0){
          diskio->status = -1;
          return NULL;
        }

        EMsgType type = *((EMsgType *) data.get());
        int32_t extern_cid, sock_idx;

        switch(type){
        case DiskIOCancel:
          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          diskio->client_valid[sock_idx] = false;
          break;
        case DiskIOEnable:
          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          diskio->client_valid[sock_idx] = true;
          break;
        default:
          assert(0);
          diskio->status = -1;
          return NULL;
        }
        continue;
      }

      if(pollitems[0].revents){
        int32_t cid;
        boost::shared_array<uint8_t> data;
        int32_t len = recv_msg(diskio->sock, cid, data);
        if(len < 0){
          assert(0);
          diskio->status = -1;
          return NULL;
        }
        //std::cout << "received from cid = " << std::hex << cid << std::dec << std::endl;
        EMsgType type = *((EMsgType *) data.get());
        Buffer *buf;
        std::string base; // for DiskIOExternal, base is actually fullpath
        int32_t extern_cid;
        int32_t sock_idx;
        if(type == DiskIORead || type == DiskIOWrite || type == DiskIOReadExternal
            || type == DiskIOWriteExternal || type == DiskIOWriteRead){
          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          buf = *((Buffer **) data.get());
          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          base = std::string((char *) data.get());
        }

        //std::cout << "request type = " << type << std::endl;

        block_id_t bid;
        int32_t extern_size;
        int32_t dbsize;
        int64_t offset;
        int32_t fidx;
        int32_t suc;
        std::string fname;
        int32_t rsize;
        int32_t wsuc;
        int32_t rd_db_id;
        EMsgType re_type;
        switch(type){
        case DiskIORead:
          bid = buf->get_block_id();

          dbsize = buf->get_db_size();
          fidx = get_file_idx(bid, dbsize, offset);
          fname = build_filename(diskio->datapath, base, fidx);

          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          if(!diskio->client_valid[sock_idx]){
            rsize = 0;
            re_type = DiskIOReadNotDone;
          }else{
            // read data from specified file, with
            rsize = dir_read(buf->get_db_ptr(), dbsize, fname.c_str(), offset);
            re_type = DiskIOReadDone;
          }

          // finished reading send back message
          suc = send_msg(diskio->sock, cid, (uint8_t *) &re_type, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          send_msg(diskio->sock, (uint8_t *) &buf, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          suc = send_msg(diskio->sock, (uint8_t *) &rsize, sizeof(int32_t), 0);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          break;

        case DiskIOWrite:

          bid = buf->get_block_id();

          dbsize = buf->get_db_size();
          fidx = get_file_idx(bid, dbsize, offset);
          fname = build_filename(diskio->datapath, base, fidx);
          // read data from specified file, with
          wsuc = dir_write(buf->get_db_ptr(), dbsize, fname.c_str(), offset);
          re_type = DiskIOWriteDone;

          // finished reading send back message
          suc = send_msg(diskio->sock, cid, (uint8_t *) &re_type, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          send_msg(diskio->sock, (uint8_t *) &buf, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          suc = send_msg(diskio->sock, (uint8_t *) &wsuc, sizeof(int32_t), 0);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          break;
        case DiskIOWriteRead:
          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          rd_db_id = *((int32_t *) data.get());

          bid = buf->get_block_id();
          dbsize = buf->get_db_size();
          fidx = get_file_idx(bid, dbsize, offset);
          fname = build_filename(diskio->datapath, base, fidx);

          // write data to
          wsuc = dir_write(buf->get_db_ptr(), dbsize, fname.c_str(), offset);

          int32_t resp_val;

          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          if(!diskio->client_valid[sock_idx]){
            resp_val = 0;
            re_type = DiskIOWriteReadWriteDone;
          }else{
            if(wsuc == 0){
              fidx = get_file_idx(rd_db_id, dbsize, offset);
              fname = build_filename(diskio->datapath, base, fidx);
              rsize = dir_read(buf->get_db_ptr(), dbsize, fname.c_str(), offset);
            }
            if(wsuc < 0 || rsize < 0){
              resp_val = -1;
            }else{
              resp_val = rsize;
            }
            re_type = DiskIOWriteReadDone;
          }
          // finished reading send back message
          suc = send_msg(diskio->sock, cid, (uint8_t *) &re_type, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          send_msg(diskio->sock, (uint8_t *) &buf, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            diskio->status = -1;
            return NULL;
          }
          suc = send_msg(diskio->sock, (uint8_t *) &resp_val, sizeof(int32_t), 0);
          if(suc < 0){
            diskio->status = -1;
            return NULL;
          }
          break;
        case DiskIOReadExternal:

          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          offset = *((int64_t *) data.get());

          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          extern_size = *((int32_t *) data.get());
          //std::cout << "size to read = " << extern_size << std::endl;

          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          if(!diskio->client_valid[sock_idx]){
            rsize = 0;
            re_type = DiskIOReadExternalNotDone;
          }else{
            //std::cout << "received request to read external data" << std::endl;
            dbsize = buf->get_db_size();
            if(extern_size > dbsize){
              assert(0);
              diskio->status = -1;
              return NULL;
            }
            fname = std::string(base);
            // read data from specified file, with
            rsize = dir_read(buf->get_db_ptr(), extern_size, fname.c_str(), offset);
            re_type = DiskIOReadExternalDone;
          }
          buf->set_valid_db_size(rsize);

          // finished reading send back message
          suc = send_msg(diskio->sock, cid, (uint8_t *) &re_type, sizeof(EMsgType),
                         ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }

          send_msg(diskio->sock, (uint8_t *) &buf, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }

          suc = send_msg(diskio->sock, (uint8_t *) &rsize, sizeof(int32_t), 0);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          break;

        case DiskIOWriteExternal:
          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          offset = *((int64_t *) data.get());

          len = recv_msg(diskio->sock, data);
          if(len < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }

          // if has been canceled, don't send response
          extern_cid = zmq_rid_to_cid(cid);
          sock_idx = cid_to_sock_idx(extern_cid);
          if(diskio->client_sock[sock_idx] == NULL) continue;

          extern_size = *((int32_t *) data.get());

          dbsize = buf->get_db_size();
          //std::cout << "extern_size = " << extern_size << " dbsize = " << dbsize << std::endl;
          assert(extern_size <= dbsize);

          fname = std::string(base);

          // read data from specified file, with
          rsize = reg_write(buf->get_db_ptr(), extern_size, fname.c_str(), offset);
          re_type = DiskIOWriteExternalDone;

          // finished reading send back message
          suc = send_msg(diskio->sock, cid, (uint8_t *) &re_type, sizeof(Buffer *),
              ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          send_msg(diskio->sock, (uint8_t *) &buf, sizeof(Buffer *), ZMQ_SNDMORE);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          suc = send_msg(diskio->sock, (uint8_t *) &rsize, sizeof(int32_t), 0);
          if(suc < 0){
            assert(0);
            diskio->status = -1;
            return NULL;
          }
          break;
        case DiskIOShutDown:
          std::cout << "diskio thread received shutdown message" << std::endl;
          return NULL;
          break;
        case DiskIOConn:
          break;
        default:
          std::cout << "!!!!!!!!!diskio thread msgtype = " << type << std::endl;
          assert(0);
          diskio->status = -1;
          return NULL;
        }
        continue;
      }

      if(pollitems[1].revents){
        zmq_event_t *event;
        boost::shared_array<uint8_t> data;
        int len;
        len = recv_msg(monitor_sock, data);

        if (len < 0){
          assert(0);
          diskio->status = -11;
          return NULL;
        }
        assert(len == sizeof(zmq_event_t));
        event = (zmq_event_t *) data.get();

        switch (event->event){
        case ZMQ_EVENT_CONNECTED:
          std::cout << "established connection." << std::endl;
          break;
        case ZMQ_EVENT_ACCEPTED:
          std::cout << "connection accepted" << std::endl;
          break;
        case ZMQ_EVENT_DISCONNECTED:
          std::cout << "client disconnected" << std::endl;
          break;
        default:
          std::cout << "unexpected event" << std::endl;
          return NULL;
        }
        continue;
      }
    }
    return NULL;
  }
예제 #14
0
파일: rm.c 프로젝트: tyll/rdup
gboolean
rm(gchar *p)
{
	int ret;
	gchar *dirp, *q;
	gchar *parent;
	GDir *d;
	struct stat st;
	struct stat *st2;

	if (opt_dry || !p)
		return TRUE;	/* noop */

	if (lstat(p, &st) == -1) {
		if (opt_verbose > 0 && errno != ENOENT)
			msgd(__func__, __LINE__,_("Failed to remove `%s\': %s"), p, strerror(errno));
		return TRUE;    /* noop */
	}

	if (S_ISDIR(st.st_mode)) {
		ret = remove(p);
		if (ret == -1) {
			switch(errno) {
				case ENOTEMPTY:
					/* recursive into this dir and do our bidding */
					if (!(d = g_dir_open(p, 0, NULL))) {
						msgd(__func__, __LINE__,_("Failed to open directory `%s\': %s"), p, strerror(errno));
						return FALSE;
					}
					while ( (dirp = (gchar*)g_dir_read_name(d))) {
						dirp = g_strdup_printf("%s/%s", p, dirp);
						rm(dirp);
						g_free(dirp);
					}
					g_dir_close(d);
					/* dir should be empty by now */
					if ((ret = remove(p)) == -1)
						msgd(__func__, __LINE__,_("Failed to remove directory `%s\': %s"),
								p, strerror(errno));
					return TRUE;
				
				case EACCES:
					/* no write to dir, make writable */
					parent = dir_parent(p);
					st2 = dir_write(parent);
					if (remove(p) == -1) {
						msgd(__func__, __LINE__,_("Failed to remove `%s\': %s"),
								p, strerror(errno));
						dir_restore(parent, st2);
						g_free(parent);
						return FALSE;
					}
					dir_restore(parent, st2);
					g_free(parent);
					return TRUE;

				default:
					/* not ENOEMPTY */
					msgd(__func__, __LINE__,_("Failed to remove directory `%s\': %s"), p, strerror(errno));
					return FALSE;
			}
		}
		return TRUE;
	}

	/* dirs are now handled */

	if (remove(p) == -1) {
		switch(errno) {
			case EACCES:
				/* we have no access, ok ... */
				q = g_strdup(p);
				parent = dirname(q);
				st2 = dir_write(parent);
				if (remove(p) == -1) {
					msgd(__func__, __LINE__,_("Failed to remove `%s\': %s"), p, strerror(errno));
					dir_restore(parent, st2);
					g_free(q);
					return FALSE;
				}
				dir_restore(parent, st2);
				g_free(q);
				return TRUE;

			case EPERM:
				/* no write on file, reuse st - and why is this needed again? */
				/* this is dead code ... */
				stat(p, &st);
				chmod(p, st.st_mode | S_IWUSR);
				if (remove(p) == -1) {
					msgd(__func__, __LINE__,_("Failed to remove `%s\': %s"),
							p, strerror(errno));
					chmod(p, st.st_mode); /* is this usefull then? */
					return FALSE;
				}
				return TRUE;	
		}
		
		msgd(__func__, __LINE__,_("Failed to remove `%s\': %s"), p, strerror(errno));
		return FALSE;
	}
	return TRUE;
}