Example #1
0
static int do_backup_phase2_client(struct config *conf, int resume, struct cntr *p1cntr, struct cntr *cntr)
{
	int ret=0;
	int quit=0;
	char cmd;
	char *buf=NULL;
	size_t len=0;
	char attribs[MAXSTRING];
	// For efficiency, open Windows files for the VSS data, and do not
	// close them until another time around the loop, when the actual
	// data is read.
	BFILE bfd;
	// Windows VSS headers tell us how much file
	// data to expect.
	size_t datalen=0;
#ifdef HAVE_WIN32
	binit(&bfd, 0);
#endif

	struct sbuf sb;

	init_sbuf(&sb);

	if(!resume)
	{
		// Only do this bit if the server did not tell us to resume.
		if(async_write_str(CMD_GEN, "backupphase2")
		  || async_read_expect(CMD_GEN, "ok"))
			return -1;
	}
	else if(conf->send_client_counters)
	{
		// On resume, the server might update the client with the
 		// counters.
		if(recv_counters(p1cntr, cntr))
			return -1;	
	}

	while(!quit)
	{
		if(async_read(&cmd, &buf, &len))
		{
			ret=-1;
			quit++;
		}
		else if(buf)
		{
			//logp("now: %c:%s\n", cmd, buf);
			if(cmd==CMD_DATAPTH)
			{
				sb.datapth=buf;
				buf=NULL;
				continue;
			}
			else if(cmd==CMD_STAT)
			{
				// Ignore the stat data - we will fill it
				// in again. Some time may have passed by now,
				// and it is best to make it as fresh as
				// possible.
				free(buf);
				buf=NULL;
				continue;
			}
			else if(cmd==CMD_FILE
			  || cmd==CMD_ENC_FILE
			  || cmd==CMD_METADATA
			  || cmd==CMD_ENC_METADATA
			  || cmd==CMD_VSS
			  || cmd==CMD_ENC_VSS
			  || cmd==CMD_VSS_T
			  || cmd==CMD_ENC_VSS_T
			  || cmd==CMD_EFS_FILE)
			{
				int forget=0;
				int64_t winattr=0;
				struct stat statbuf;
				char *extrameta=NULL;
				size_t elen=0;
				unsigned long long bytes=0;
				FILE *fp=NULL;
				int compression=conf->compression;

				sb.path=buf;
				buf=NULL;

#ifdef HAVE_WIN32
				if(win32_lstat(sb.path, &statbuf, &winattr))
#else
				if(lstat(sb.path, &statbuf))
#endif
				{
					logw(cntr, "Path has vanished: %s", sb.path);
					if(forget_file(&sb, cmd, cntr))
					{
						ret=-1;
						quit++;
					}
					free_sbuf(&sb);
					continue;
				}

				if(conf->min_file_size
				  && statbuf.st_size<
					(boffset_t)conf->min_file_size
				  && (cmd==CMD_FILE
				  || cmd==CMD_ENC_FILE
				  || cmd==CMD_EFS_FILE))
				{
					logw(cntr, "File size decreased below min_file_size after initial scan: %c:%s", cmd, sb.path);
					forget++;
				}
				else if(conf->max_file_size
				  && statbuf.st_size>
					(boffset_t)conf->max_file_size
				  && (cmd==CMD_FILE
				  || cmd==CMD_ENC_FILE
				  || cmd==CMD_EFS_FILE))
				{
					logw(cntr, "File size increased above max_file_size after initial scan: %c:%s", cmd, sb.path);
					forget++;
				}

				if(!forget)
				{
					compression=in_exclude_comp(conf->excom,
					  conf->excmcount, sb.path,
					  conf->compression);
					encode_stat(attribs,
					  &statbuf, winattr, compression);
					if(open_file_for_send(
#ifdef HAVE_WIN32
						&bfd, NULL,
#else
						NULL, &fp,
#endif
						sb.path, winattr,
						&datalen, cntr))
							forget++;
				}

				if(forget)
				{
					if(forget_file(&sb, cmd, cntr))
					{
						ret=-1;
						quit++;
					}
					free_sbuf(&sb);
					continue;
				}

				if(cmd==CMD_METADATA
				  || cmd==CMD_ENC_METADATA
				  || cmd==CMD_VSS
				  || cmd==CMD_ENC_VSS
#ifdef HAVE_WIN32
				  || conf->strip_vss
#endif
				  )
				{
					if(get_extrameta(
#ifdef HAVE_WIN32
						&bfd,
#else
						NULL,
#endif
						sb.path,
						&statbuf, &extrameta, &elen,
						winattr, cntr,
						&datalen))
					{
						logw(cntr, "Meta data error for %s", sb.path);
						free_sbuf(&sb);
						close_file_for_send(&bfd, &fp);
						continue;
					}
					if(extrameta)
					{
#ifdef HAVE_WIN32
						if(conf->strip_vss)
						{
							free(extrameta);
							extrameta=NULL;
							elen=0;
						}
#endif
					}
					else
					{
						logw(cntr, "No meta data after all: %s", sb.path);
						free_sbuf(&sb);
						close_file_for_send(&bfd, &fp);
						continue;
					}
				}

				if(cmd==CMD_FILE && sb.datapth)
				{
					unsigned long long sentbytes=0;
					// Need to do sig/delta stuff.
					if(async_write_str(CMD_DATAPTH, sb.datapth)
					  || async_write_str(CMD_STAT, attribs)
					  || async_write_str(CMD_FILE, sb.path)
					  || load_signature_and_send_delta(
						&bfd, fp,
						&bytes, &sentbytes, cntr,
						datalen))
					{
						logp("error in sig/delta for %s (%s)\n", sb.path, sb.datapth);
						ret=-1;
						quit++;
					}
					else
					{
						do_filecounter(cntr, CMD_FILE_CHANGED, 1);
						do_filecounter_bytes(cntr, bytes);
						do_filecounter_sentbytes(cntr, sentbytes);
					}
				}
				else
				{
					//logp("need to send whole file: %s\n",
					//	sb.path);
					// send the whole file.

					if((async_write_str(CMD_STAT, attribs)
					  || async_write_str(cmd, sb.path))
					  || send_whole_file_w(cmd, sb.path,
						NULL, 0, &bytes,
						conf->encryption_password,
						cntr, compression,
						&bfd, fp,
						extrameta, elen,
						datalen))
					{
						ret=-1;
						quit++;
					}
					else
					{
						do_filecounter(cntr, cmd, 1);
						do_filecounter_bytes(cntr, bytes);
						do_filecounter_sentbytes(cntr, bytes);
					}
				}
#ifdef HAVE_WIN32
				// If using Windows do not close bfd - it needs
				// to stay open to read VSS/file data/VSS.
				// It will get closed either when given a
				// different file path, or when this function
				// exits.
				
				//if(cmd!=CMD_VSS
				// && cmd!=CMD_ENC_VSS)
				//	close_file_for_send(&bfd, NULL);
#else
				close_file_for_send(NULL, &fp);
#endif
				free_sbuf(&sb);
				if(extrameta) free(extrameta);
			}
			else if(cmd==CMD_WARNING)
			{
				do_filecounter(cntr, cmd, 0);
				free(buf);
				buf=NULL;
			}
			else if(cmd==CMD_GEN && !strcmp(buf, "backupphase2end"))
			{
				if(async_write_str(CMD_GEN, "okbackupphase2end"))
					ret=-1;
				quit++;
			}
			else
			{
				logp("unexpected cmd from server: %c %s\n",
					cmd, buf);
				ret=-1;
				quit++;
				free(buf);
				buf=NULL;
			}
		}
	}
#ifdef HAVE_WIN32
	// It is possible for a bfd to still be open.
	close_file_for_send(&bfd, NULL);
#endif
	return ret;
}
Example #2
0
bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
{
   BSOCK *sd = jcr->store_bsock;
   POOL_MEM attribs(PM_NAME),
            attribsExBuf(PM_NAME);
   char *attribsEx = NULL;
   int attr_stream;
   int comp_len;
   bool status;
   int hangup = get_hangup();
#ifdef FD_NO_SEND_TEST
   return true;
#endif

   Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
   /** Find what data stream we will use, then encode the attributes */
   if ((data_stream = select_data_stream(ff_pkt, me->compatible)) == STREAM_NONE) {
      /* This should not happen */
      Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
      return false;
   }
   encode_stat(attribs.c_str(), &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream);

   /** Now possibly extend the attributes */
   if (IS_FT_OBJECT(ff_pkt->type)) {
      attr_stream = STREAM_RESTORE_OBJECT;
   } else {
      attribsEx = attribsExBuf.c_str();
      attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
   }

   Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs.c_str(), attribsEx);

   jcr->lock();
   jcr->JobFiles++;                    /* increment number of files sent */
   ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
   pm_strcpy(jcr->last_fname, ff_pkt->fname);
   jcr->unlock();

   /*
    * Debug code: check if we must hangup
    */
   if (hangup && (jcr->JobFiles > (uint32_t)hangup)) {
      jcr->setJobStatus(JS_Incomplete);
      Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
      set_hangup(0);
      return false;
   }

   /**
    * Send Attributes header to Storage daemon
    *    <file-index> <stream> <info>
    */
   if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
      if (!jcr->is_canceled() && !jcr->is_incomplete()) {
         Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
      }
      return false;
   }
   Dmsg1(300, ">stored: attrhdr %s", sd->msg);

   /**
    * Send file attributes to Storage daemon
    *   File_index
    *   File type
    *   Filename (full path)
    *   Encoded attributes
    *   Link name (if type==FT_LNK or FT_LNKSAVED)
    *   Encoded extended-attributes (for Win32)
    *   Delta Sequence Number
    *
    * or send Restore Object to Storage daemon
    *   File_index
    *   File_type
    *   Object_index
    *   Object_len  (possibly compressed)
    *   Object_full_len (not compressed)
    *   Object_compression
    *   Plugin_name
    *   Object_name
    *   Binary Object data
    *
    * For a directory, link is the same as fname, but with trailing
    * slash. For a linked file, link is the link.
    */
   if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { /* already stripped */
      strip_path(ff_pkt);
   }
   switch (ff_pkt->type) {
   case FT_JUNCTION:
   case FT_LNK:
   case FT_LNKSAVED:
      Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
      status = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
                         ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0,
                         ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
      break;
   case FT_DIREND:
   case FT_REPARSE:
      /* Here link is the canonical filename (i.e. with trailing slash) */
      status = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
                         ff_pkt->type, ff_pkt->link, 0, attribs.c_str(), 0, 0,
                         attribsEx, 0, ff_pkt->delta_seq, 0);
      break;
   case FT_PLUGIN_CONFIG:
   case FT_RESTORE_FIRST:
      comp_len = ff_pkt->object_len;
      ff_pkt->object_compression = 0;

      if (ff_pkt->object_len > 1000) {
         /*
          * Big object, compress it
          */
         comp_len = compressBound(ff_pkt->object_len);
         POOLMEM *comp_obj = get_memory(comp_len);
         /*
          * FIXME: check Zdeflate error
          */
         Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
         if (comp_len < ff_pkt->object_len) {
            ff_pkt->object = comp_obj;
            ff_pkt->object_compression = 1;    /* zlib level 9 compression */
         } else {
            /*
             * Uncompressed object smaller, use it
             */
            comp_len = ff_pkt->object_len;
         }
         Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
      }

      sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
                        jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
                        comp_len, ff_pkt->object_len, ff_pkt->object_compression,
                        ff_pkt->fname, 0, ff_pkt->object_name, 0);
      sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
      memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);

      /*
       * Note we send one extra byte so Dir can store zero after object
       */
      sd->msglen += comp_len + 1;
      status = sd->send();
      if (ff_pkt->object_compression) {
         free_and_null_pool_memory(ff_pkt->object);
      }
      break;
   case FT_REG:
      status = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
                         ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0, 0,
                         attribsEx, 0, ff_pkt->delta_seq, 0);
      break;
   default:
      status = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
                         ff_pkt->type, ff_pkt->fname, 0, attribs.c_str(), 0, 0,
                         attribsEx, 0, ff_pkt->delta_seq, 0);
      break;
   }

   if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) {
      unstrip_path(ff_pkt);
   }

   Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
   if (!status && !jcr->is_job_canceled()) {
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"), sd->bstrerror());
   }

   sd->signal(BNET_EOD);            /* indicate end of attributes data */

   return status;
}
Example #3
0
void prepare_reply(p9_obj_t *T_p9_obj, p9_obj_t *R_p9_obj, fid_list **fid_table){
	fid_node *fnode;
	switch(T_p9_obj -> type){
		case P9_TVERSION:
			R_p9_obj -> size = 19; /* this server only understands 9p2000 */
			R_p9_obj -> type = P9_RVERSION;
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> msize = T_p9_obj -> msize;
			R_p9_obj -> version_len = 6;
			R_p9_obj -> version = (char *) malloc(20 * sizeof(char));;
			strcpy(R_p9_obj -> version, "9P2000");
			break;
		case P9_TATTACH:{
			int aname_len;
			char *aname;
			char *corrected_aname;
			aname_len = T_p9_obj -> aname_len;
			aname = T_p9_obj -> aname;
			corrected_aname = (char *) malloc(aname_len + 2);
			bzero(corrected_aname, aname_len + 2);
			strcat(corrected_aname, "/");
			strcat(corrected_aname, aname);
			R_p9_obj -> size = 20; /* this is the size of the RMessage */
			R_p9_obj -> qid = (qid_t *) malloc (sizeof(qid_t));
			make_qid_from_UNIX_file(corrected_aname, R_p9_obj -> qid);
			/* adding the entry to the fid table */
			fid_table_add_fid(fid_table, T_p9_obj -> fid, corrected_aname);
			free(corrected_aname);
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> type = P9_RATTACH;
			break;
		}
		case P9_TSTAT:
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> type = P9_RSTAT;
			R_p9_obj -> stat = (stat_t *) malloc(sizeof(stat_t));
			fnode = fid_table_find_fid(fid_table, T_p9_obj -> fid);
			if(fnode == NULL){ //stating a file that does not exist in the fid table
				perror("TSTAT a file that is not in the fid table\n");
				exit(1);
			}
			make_stat_from_UNIX_file(fnode -> path, R_p9_obj -> stat);
			if(R_p9_obj -> stat -> qid -> type == 128){
				R_p9_obj -> stat -> length = 0;
			}
			/* Handling the case when stating a virtual disk. Should send the length of the logical disk not the actual descriptor file */
			if(R_p9_obj -> stat -> qid -> type == 0 && DiskLib_IsDescriptorFile(fnode -> path)){
				DiskLibError diskError;
				DiskHandle   disk_handle;
				DiskLibInfo *disk_info;
				diskError = DiskLib_OpenWithInfo(fnode -> path, OPEN_NOIO, NULL, &disk_handle, &disk_info);
				if(!DiskLib_IsSuccess(diskError)){
					printf(DiskLib_Err2String(diskError));
					exit(1);
				}
				R_p9_obj -> stat -> length = disk_info -> capacity * DISKLIB_SECTOR_SIZE;
				free(disk_info);
				DiskLib_Close(disk_handle);
			}
			R_p9_obj -> stat_len = get_stat_length(R_p9_obj -> stat) + 2; //the stat length should be the length of the stat + the size
			R_p9_obj -> size = 7 + 2 + R_p9_obj -> stat_len; //stat[n] and the size field
			break;
		case P9_TWALK:
			/* if newfid is in use, an RERROR should be returned. The only exception is when newfid is the same as fid	*/
			/* The case where newfid == fid should be handled separately
			 * 												*/
			if(fid_table_find_fid(fid_table, T_p9_obj -> newfid) != NULL && T_p9_obj -> newfid != T_p9_obj -> fid){
				char *error_msg;
				int error_len;
				R_p9_obj -> type = P9_RERROR;
				error_msg = "newfid is in use and it is not equal to fid\n";
				error_len = strlen(error_msg);
				R_p9_obj -> size = 7 + 2 + error_len;
				R_p9_obj -> ename_len = error_len;
				R_p9_obj -> ename = error_msg;
				R_p9_obj -> tag = T_p9_obj -> tag;
			}
			else{ //newfid is not being used or newfid == fid (should be the same case until we change the fid_table)

				fid_node *fnode;
				fnode = fid_table_find_fid(fid_table, T_p9_obj -> fid);
				if(fnode == NULL || fnode -> object_handle != NULL){
					if(!fnode)perror("TWALK message received with an fid that is open\n");
					else perror("TWALK message received with an fid that does not exist in the fid table");
					exit(1);
				}
				if(T_p9_obj -> nwname == 0){
					fid_table_add_fid(fid_table, T_p9_obj -> newfid, fnode -> path);
					R_p9_obj -> size = 7 + 2;
					R_p9_obj -> type = P9_RWALK;
					R_p9_obj -> tag = T_p9_obj -> tag;
					R_p9_obj -> nwqid = 0;
				}
				else{ //nwname != 0
					/* Check if the first element is walkable, if not an RERROR will return */
					/* first get the number of nwqids */
					char *path;
					int nwqid, i;
					path = (char *)malloc(1000 * sizeof(char));
					strcpy(path, fnode -> path);
					assert(path);
					nwqid = 0;
					for(i = 0; i < T_p9_obj -> nwname; i++){
						strcat(path, "/");
						strcat(path, (T_p9_obj -> wname_list + i) -> wname);
						//fprintf(stderr, "directory path is %s\n", path);
						if(is_file_exists(path)) nwqid++;
					}

					if(nwqid == 0){
						/* First element does not exist. return RERROR */
						char *error_msg;
						int error_len;
						R_p9_obj -> type = P9_RERROR;
						error_msg = "No such file or directory";
						error_len = strlen(error_msg);
						R_p9_obj -> size = 7 + 2 + error_len;
						R_p9_obj -> ename_len = error_len;
						R_p9_obj -> ename = (char *) malloc(error_len * sizeof(char) + 1);
						bzero(R_p9_obj -> ename, error_len + 1);
						strcpy(R_p9_obj -> ename, error_msg);
						R_p9_obj -> tag = T_p9_obj -> tag;
						free(path);
					}
						/* The first element is walkabale. RWALK will return	*/
					else{
						int i;
						bzero(path, 1000);
						strcpy(path, fnode -> path);
						R_p9_obj -> type = P9_RWALK;
						R_p9_obj -> tag = T_p9_obj -> tag;
						R_p9_obj -> size = 7 + 2 + nwqid * 13;
						R_p9_obj -> nwqid = nwqid;
						R_p9_obj -> wqid = (qid_t **) malloc(nwqid * sizeof(qid_t *));
						for(i = 0; i < nwqid; i++){
							qid_t *qid;
							strcat(path, "/");
							strcat(path, (T_p9_obj -> wname_list + i) -> wname);
							qid = (qid_t *) malloc(sizeof(qid_t));
							make_qid_from_UNIX_file(path, qid);
							R_p9_obj -> wqid[i] = qid;

						}
						/* newfid will be affected only if nwqid == nwnames */

						if(nwqid == T_p9_obj -> nwname){
							/* path is now the full path */
							fid_node *fnode;
							fnode = fid_table_find_fid(fid_table, T_p9_obj -> newfid);
							if(fnode != NULL){
								//fid = newfid case
								fnode -> fid = T_p9_obj -> newfid;
								strncpy(fnode -> path, path, 999);
							}
							else
								fid_table_add_fid(fid_table, T_p9_obj -> newfid, path);
						}
						free(path);
					}
				}
			}
			break;
		case P9_TCLUNK:
			/* Should remove the fid from the fid directory */
			/* the remove fid should close any file or directory opened by this fid */
			if(fid_table_remove_fid(fid_table, T_p9_obj -> fid) == -1){
				int error_len;
				char *error_msg;
				perror("TCLUNK received for an fid that does not exist\n ");
				error_msg = strerror(EBADF);
                                error_len = strlen(error_msg);
                                R_p9_obj -> size = 7 + 2 + error_len;
                                R_p9_obj -> ename_len = error_len;
				R_p9_obj -> ename = (char *) malloc(error_len + 1);
				bzero(R_p9_obj -> ename, error_len + 1);
                                strcpy(R_p9_obj -> ename , error_msg);
                                R_p9_obj -> tag = T_p9_obj -> tag;
			}
			else{
				assert(fid_table_find_fid(fid_table, T_p9_obj -> fid) == NULL);
				R_p9_obj -> tag = T_p9_obj -> tag;
				R_p9_obj -> type = P9_RCLUNK;
				R_p9_obj -> size = 7;
			}
			break;
		case P9_TOPEN:
		{
			int p9_mode;
			p9_mode = 0;
			fnode = fid_table_find_fid(fid_table, T_p9_obj -> fid);
			assert(fnode != NULL);
			assert(fnode -> fid == T_p9_obj -> fid);
			assert(fnode -> object_handle == NULL);
			/* if fid refers to a directory, just send back the ROPEN message */
			/* if fid refers to a file, open the file, change the file descriptor, and send the ROPEN message */
			R_p9_obj -> size = 4 + 1 + 2 + 13 + 4;
			R_p9_obj -> type = P9_ROPEN;
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> qid = (qid_t *) malloc(sizeof(qid_t));
			make_qid_from_UNIX_file(fnode->path, R_p9_obj -> qid);
			R_p9_obj -> iounit = 0;
			if(!DiskLib_IsDescriptorFile(fnode -> path) && (R_p9_obj -> qid -> type == 0 || R_p9_obj -> qid -> type == 2)){ //this is a regular file or a symbolic link and NOT a logical virtual disk
				ObjHandle *object_handle;
				ObjOpenParams openParams;
				ObjLibError objError;
				object_handle = (ObjHandle *) malloc(sizeof(ObjHandle));
				assert((T_p9_obj -> mode & 0x10) != 0x10 );
				if((T_p9_obj->mode != 0) && (T_p9_obj -> mode != 1) && (T_p9_obj -> mode != 2)){
					printf("UNFAMILIAR MODE %d\n", T_p9_obj->mode);
					exit(1);
				}
				switch(T_p9_obj -> mode & 3){
					case 0:
#ifdef DEBUG
						printf("opening file %s for read only\n", fnode -> path);
#endif
						p9_mode = OBJ_OPEN_ACCESS_READ;
						break;
					case 1:
#ifdef DEBUG
						printf("opening file %s for write only\n", fnode -> path);
#endif
						p9_mode = OBJ_OPEN_ACCESS_WRITE;
						break;
					case 2:
#ifdef DEBUG
						printf("opening file %s for read write\n", fnode -> path);
#endif
						p9_mode = OBJ_OPEN_ACCESS_READ | OBJ_OPEN_ACCESS_WRITE;
						//printf("OPENING FILE FOR READ AND WRITE IS IN OBJECT LIB\n");
						break;
					case 3:
						p9_mode = OBJ_OPEN_ACCESS_READ;
						break;
					default:
						printf("You should never reach here\n");
						exit(1);
				}
				/* The following cases are not handled since there is no ObjLib flags that represent them */
				/*
				if (T_p9_obj -> mode & 0x10)
					p9_mode |= O_TRUNC;

				if (T_p9_obj -> mode & 0x80)
				    p9_mode |= O_APPEND;

				if (T_p9_obj -> mode & 0x04)
				    p9_mode |= O_EXCL;
				*/

				/* Opening the file based on the requested mode */
				//fd = open(fnode -> path, p9_mode);
				/* TODO: maybe the object class type should change */
				ObjLib_SetOpenParams(&openParams, fnode->path, NULL, OBJTYPE_CLASS_GENERIC, p9_mode, OBJ_OPEN, NULL, 0, NULL);
				objError = ObjLib_Open(&openParams, object_handle);
			        if(!ObjLib_IsSuccess(objError)){
					printf("Error opening\n");
					exit(1);
				} 	

				/* Assigning the file descriptor to the fid node */
				fnode -> object_handle = object_handle;

				if(fnode -> object_handle == NULL){
					R_p9_obj -> type =  P9_RERROR;
					R_p9_obj -> ename_len = strlen(strerror(errno));
					R_p9_obj -> ename = (char *) malloc(R_p9_obj -> ename_len + 1);
					bzero(R_p9_obj -> ename, R_p9_obj -> ename_len + 1);
					strcpy(R_p9_obj -> ename, strerror(errno));
					R_p9_obj -> size = 4 + 1 + 2 + 2 + R_p9_obj -> ename_len;
				}
				else assert(fnode -> object_handle != NULL);
			}
			/* Handling the case of a logical virtual disk */
			else if(DiskLib_IsDescriptorFile(fnode -> path) && (R_p9_obj -> qid -> type == 0)){
				DiskHandle *disk_handle;
				DiskLibError diskError;
				disk_handle = (DiskHandle *)malloc(sizeof(DiskHandle));
				assert((T_p9_obj -> mode & 0x10) != 0x10 );
                                if((T_p9_obj->mode != 0) && (T_p9_obj -> mode != 1) && (T_p9_obj -> mode != 2)){
                                        printf("UNFAMILIAR MODE %d\n", T_p9_obj->mode);
                                        exit(1);
                                }
				/* probably for disks you need to open them for read and write since you can only read and write sectors */
				switch(T_p9_obj -> mode & 3){
					case 0:
						p9_mode = OPEN_PARENT | OPEN_LOCK | OPEN_RDONLY;
						break;
					case 1:
						p9_mode = OPEN_PARENT | OPEN_LOCK;
						break;
					case 2:
						p9_mode = OPEN_PARENT | OPEN_LOCK;
						break;
					case 3:
						p9_mode = OPEN_PARENT | OPEN_LOCK | OPEN_RDONLY;
						break;
					default:
						printf("You should have never reached this point");
						exit(1);
				}
				diskError = DiskLib_Open(fnode -> path, p9_mode, NULL, disk_handle);
				if(!DiskLib_IsSuccess(diskError)){
					printf("Error opening virtual disk during TOpen");
					exit(1);
				}
				/* adding the disk handle to the fnode */
				fnode -> disk_handle = disk_handle;
				assert(fnode -> disk_handle != NULL);
			}
			else{ //file is a directory
				fnode -> dd = opendir(fnode -> path);
				if(fnode -> dd == NULL){
					R_p9_obj -> type =  P9_RERROR;
					R_p9_obj -> ename_len = strlen(strerror(errno));
					R_p9_obj -> ename = (char *) malloc(R_p9_obj -> ename_len + 1);
					bzero(R_p9_obj -> ename, R_p9_obj -> ename_len + 1);
				        strcpy(R_p9_obj -> ename, strerror(errno));
					R_p9_obj -> size = 4 + 1 + 2 + 2 + R_p9_obj -> ename_len;
				}
				/* handle permissions and rw access */
			}
			break;
		} // ending case scope
		case P9_TREAD:
			{//defining a scope in the case statement
			int fid;
			uint8_t *data;
			//fprintf(stderr, "I am here!");
			fid = T_p9_obj -> fid;
			fnode = fid_table_find_fid(fid_table, fid);
			assert(fnode != NULL);
			//fprintf(stderr, "I am here tooooo\n");
			data = (uint8_t *) malloc(T_p9_obj -> count * sizeof(uint8_t));
			//fprintf(stderr, "before zeroing\n");
			bzero(data, T_p9_obj -> count);
			//fprintf(stderr, "after zeroing\n");
			/* handling the directory case */
			assert(fnode);
			//fprintf(stderr, "fd is %d\n", fnode -> fd);
			if(fnode -> object_handle == NULL && fnode -> disk_handle == NULL){ //this must be a directory then
				struct dirent *entry;
				int idx;
				char *newpathname;
				newpathname = (char *) malloc(1000 * sizeof(char));
				idx = 0;
				assert(fnode -> dd);
#ifdef DEBUG
				//fprintf(stderr, "Attempting to read directory %s\n", fnode -> dd);
#endif

				while((entry = readdir(fnode -> dd))){
#ifdef DEBUG
					//fprintf(stderr, "entry is %s\n", entry->d_name);
#endif
					char *entry_name;
					stat_t *s;
					bzero(newpathname, 1000);
					strcpy(newpathname, fnode -> path);
					if((strcmp(entry->d_name, ".") == 0)  || (strcmp(entry->d_name, "..") == 0))
						continue;
					entry_name = entry->d_name;
					newpathname = strcat(newpathname, "/");
					newpathname = strcat(newpathname, entry_name);
					s = (stat_t *) malloc(sizeof(stat_t));
#ifdef DEBUG
					//fprintf(stderr, "Attempting to create stat now\n");
					//fprintf(stderr, "stating pathname: %s\n", newpathname);
#endif
					make_stat_from_UNIX_file(newpathname, s);
					//int_to_buffer_bytes(get_stat_length(s) + 2, data, idx, 2);
					//idx += 2;
					if(DiskLib_IsDescriptorFile(newpathname)){
						DiskLibError diskError;
                                		DiskHandle   disk_handle;
                                		DiskLibInfo *disk_info;
                                		diskError = DiskLib_OpenWithInfo(newpathname, OPEN_NOIO, NULL, &disk_handle, &disk_info);
                                		if(!DiskLib_IsSuccess(diskError)){
                                        		printf(DiskLib_Err2String(diskError));
                                        		exit(1);
                                		}
                                		s -> length = disk_info -> capacity * DISKLIB_SECTOR_SIZE;
                                		free(disk_info);
                                		DiskLib_Close(disk_handle);
					}
					encode_stat(s, data, idx, get_stat_length(s));
					idx += (2 + get_stat_length(s));

					destroy_stat(s);
					/* just a quick hack */
					if(idx > ((90.0 / 100.0) * (float)(T_p9_obj->count))) break; //this is a safety factor to make sure we are not exceeding the Tcount
					assert(idx <= T_p9_obj -> count);
				}
				free(newpathname);
				R_p9_obj -> count = idx;
				R_p9_obj -> data  = data;
				R_p9_obj -> size = 4 + 2 + 4 + 1  + R_p9_obj -> count;
				R_p9_obj -> tag = T_p9_obj -> tag;
				R_p9_obj -> type = P9_RREAD;
			}
			/* handling the file case */
			else if (fnode -> disk_handle == NULL){ /* not a logical virtual disk file */ 
				int count, read_bytes;
				
				//fprintf(stderr, "inside else\n");
				
				count = T_p9_obj -> count;
				assert(ObjLib_IsHandleValid(*(fnode -> object_handle)));
				read_bytes = ESX_read(fnode -> object_handle, data, T_p9_obj -> offset, count);
				if(read_bytes >= 0){
					R_p9_obj -> count = read_bytes;
					R_p9_obj -> data = data;
					R_p9_obj -> size = 4 + 2 + 4 + 1 + R_p9_obj -> count;
					R_p9_obj -> tag = T_p9_obj -> tag;
					R_p9_obj -> type = P9_RREAD;
				}
				else{
					R_p9_obj -> type =  P9_RERROR;
					R_p9_obj -> ename_len = strlen(strerror(errno));
					R_p9_obj -> tag = T_p9_obj -> tag;
					R_p9_obj -> ename = (char *) malloc(R_p9_obj -> ename_len + 1);
					bzero(R_p9_obj -> ename, R_p9_obj -> ename_len + 1);
					strcpy(R_p9_obj -> ename, strerror(errno));
					R_p9_obj -> size = 4 + 1 + 2 + 2 + R_p9_obj -> ename_len;
				}
			}
			/* Now handling the logical virtual disk case */
			else{
				int count, read_bytes;
				count = T_p9_obj -> count;
				//assert(DiskLib_IsHandleValid(fnode -> disk_handle));
				read_bytes = ESX_Vdisk_Read(fnode -> disk_handle, data, T_p9_obj -> offset, count);
				if(read_bytes >= 0){
                                        R_p9_obj -> count = read_bytes;
                                        R_p9_obj -> data = data;
                                        R_p9_obj -> size = 4 + 2 + 4 + 1 + R_p9_obj -> count;
                                        R_p9_obj -> tag = T_p9_obj -> tag;
                                        R_p9_obj -> type = P9_RREAD;
                                }
                                else{
                                        R_p9_obj -> type =  P9_RERROR;
                                        R_p9_obj -> ename_len = strlen(strerror(errno));
                                        R_p9_obj -> tag = T_p9_obj -> tag;
                                        R_p9_obj -> ename = (char *) malloc(R_p9_obj -> ename_len + 1);
                                        bzero(R_p9_obj -> ename, R_p9_obj -> ename_len + 1);
                                        strcpy(R_p9_obj -> ename, strerror(errno));
                                        R_p9_obj -> size = 4 + 1 + 2 + 2 + R_p9_obj -> ename_len;
                                }
			}

			break;
			}//ending scope
		case P9_TWRITE:
		{
			int fid, count, write_count;
#ifdef DEBUG
			int i;
#endif
			unsigned long long offset;
			fid_node *fnode;
			R_p9_obj -> size = 11;
			R_p9_obj -> type = P9_RWRITE;
			R_p9_obj -> tag = T_p9_obj -> tag;
			fid = T_p9_obj -> fid;
			offset = T_p9_obj -> offset;
			count = T_p9_obj -> count;
			fnode = fid_table_find_fid(fid_table, fid);
			assert(fnode != NULL);
			assert((fnode -> object_handle != NULL) || (fnode -> disk_handle != NULL)); /* file must be open */
#ifdef DEBUG
			printf("DATA\n");
			for(i = 0; i < T_p9_obj -> count; i++){
				printf("%d ", T_p9_obj -> data[i]);
			}
#endif
			if(fnode -> object_handle) write_count = ESX_write(fnode -> object_handle, offset, T_p9_obj -> data, count);
			/* this is handling the logical virtual disk write case */
			else write_count = ESX_Vdisk_Write(fnode -> disk_handle, offset, T_p9_obj -> data, count);
			R_p9_obj -> count = write_count;
			break;
		}//ending scope
		case P9_TCREATE:
			{
			int fid;
			struct stat *s;
			uint32_t perm;
			char *newpathname;
			fid = T_p9_obj -> fid;
			fnode = fid_table_find_fid(fid_table, fid);
			if(fnode == NULL){
				perror("Trying to create a new file in a directory that does not exist in the fid_table\n");
				exit(1);
			}
			s = (struct stat *)malloc(sizeof(struct stat));
			if(lstat(fnode -> path, s)==0){
				if(!S_ISDIR(s->st_mode)){
					perror("The fid belongs to a file not a directory. Can't execute TCREATE\n");
				}
			}
			else{
				perror("cant stat fnode->path\n");
				exit(1);
			}

			perm = T_p9_obj -> perm;
			if((perm & 0x80000000) == 0x80000000){ //this is a directory

				create_directory(fnode->path, T_p9_obj -> name);
  		    }
			else{//a file needs to be create
				create_file(fnode->path, T_p9_obj -> name, perm);
			}
			/* now the newly created file needs to be opened */
			R_p9_obj -> size = 4 + 1 + 2 + 13 + 4;
			R_p9_obj -> type = P9_RCREATE;
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> qid = (qid_t *) malloc(sizeof(qid_t));
			newpathname = (char *)malloc(1000);
			bzero(newpathname, 1000);
			strcat(newpathname, fnode->path);
			strcat(newpathname, "/");
			strcat(newpathname, T_p9_obj -> name);
#ifdef DEBUG
			printf("ATTEMPTING TO CREATE %s\n", newpathname);
#endif
			/* this fid should represent the newly created file now */
			fnode -> path = newpathname;
			fnode -> dd = 0;
			fnode -> object_handle = NULL;

			make_qid_from_UNIX_file(fnode->path, R_p9_obj -> qid);
			R_p9_obj -> iounit = 0;
			if(R_p9_obj -> qid -> type == 0 ){ //this is a regular file
				int p9_mode;
				ObjHandle *object_handle;
                                ObjOpenParams openParams;
                                ObjLibError objError;
				object_handle = (ObjHandle *) malloc(sizeof(ObjHandle));
                                assert((T_p9_obj -> mode & 0x10) != 0x10 );
                                if((T_p9_obj->mode != 0) && (T_p9_obj -> mode != 1) && (T_p9_obj -> mode != 2)){
                                        printf("UNFAMILIAR MODE %d\n", T_p9_obj->mode);
                                        exit(1);
                                }
				p9_mode = 0;
                                switch(T_p9_obj -> mode & 3){
                                        case 0:
#ifdef DEBUG
                                                printf("opening file %s for read only\n", fnode -> path);
#endif
                                                p9_mode = OBJ_OPEN_ACCESS_READ;
                                                break;
                                        case 1:
#ifdef DEBUG
                                                printf("opening file %s for write only\n", fnode -> path);
#endif
                                                p9_mode = OBJ_OPEN_ACCESS_WRITE;
                                                break;
                                        case 2:
#ifdef DEBUG
                                                printf("opening file %s for read write\n", fnode -> path);
#endif
						p9_mode = OBJ_OPEN_ACCESS_READ | OBJ_OPEN_ACCESS_WRITE;
						//printf("OPENING FILE FOR READ AND WRITE IS NOT SUPPORTED IN OBJECT LIB\n");
                                                
                                                break;
                                        case 3:
                                                p9_mode = OBJ_OPEN_ACCESS_READ;
                                                break;
                                        default:
                                                printf("You should never reach here\n");
                                                exit(1);
						break;
				}
                                ObjLib_SetOpenParams(&openParams, fnode->path, NULL, OBJTYPE_CLASS_GENERIC, p9_mode, OBJ_OPEN, NULL, 0, NULL);
                                objError = ObjLib_Open(&openParams, object_handle);
				if(!ObjLib_IsSuccess(objError)){
					printf("Error opening\n");
					exit(1);
				}

                                /* Assigning the file descriptor to the fid node */
                                fnode -> object_handle = object_handle;

                                if(fnode -> object_handle == NULL){
                                        R_p9_obj -> type =  P9_RERROR;
                                        R_p9_obj -> ename_len = strlen(strerror(errno));
                                        R_p9_obj -> ename = (char *) malloc(R_p9_obj -> ename_len + 1);
                                        bzero(R_p9_obj -> ename, R_p9_obj -> ename_len + 1);
                                        strcpy(R_p9_obj -> ename, strerror(errno));
                                        R_p9_obj -> size = 4 + 1 + 2 + 2 + R_p9_obj -> ename_len;
                                }
				else{
					assert(fnode -> object_handle != NULL);
				}
			}
			else{ //file is a directory
				fnode -> dd = opendir(fnode -> path);
				/* handle permissions and rw access */
			}
			free(s); //free the temporary allocated stat data structure

			break;
			}//end scope
		case P9_TREMOVE:{
			int fid;
			R_p9_obj -> size = 7;
			R_p9_obj -> type = P9_RREMOVE;
			R_p9_obj -> tag = T_p9_obj -> tag;
			fid = T_p9_obj -> fid;
			fnode = fid_table_find_fid(fid_table, fid);
			assert(fnode != NULL);
			assert(fnode->path != NULL);
			if(UNIX_remove(fnode->path) != 0){
				perror("failed to remove\n");
				exit(1);
			}
			if(fid_table_remove_fid(fid_table, fid) == -1){
				perror("TRREMOVE");
				exit(1);
			}
			assert(fid_table_find_fid(fid_table, T_p9_obj -> fid) == NULL);
			break;
			}//end scope
		case P9_TWSTAT:
		{
			int fid;
			fid_node *fnode;
			stat_t *s_new;
			stat_t *s_old;
			fid = T_p9_obj -> fid;
			s_new = T_p9_obj -> stat;
			fnode = fid_table_find_fid(fid_table, fid);
			if(fnode == NULL){
				perror("writing stat to non existing file\n");
				exit(1);
			}
			s_old = (stat_t *)malloc(sizeof(stat_t));
			make_stat_from_UNIX_file(fnode->path, s_old);
			/* now you have s_new and s_old. Check differences and call the appropriate UNIX api */
			/* it doesn't make any sense to change the type, dev, qid, atime, mtime, muid */
			/* only name, uid, gid, permission part of the mode can be changed
			 *
			 */
			/* it does not make any sense to change the length */
			if((strcmp(s_new -> name, "")!= 0) && (strcmp(s_old -> name, s_new -> name) != 0)){
#ifdef DEBUG
				printf("RENAMING: %s to %s\n", s_old -> name, s_new -> name);
#endif
				if(T_p9_obj -> stat -> qid -> type == 128){
					/* TODO: check permissions */
					UNIX_rename_directory(fnode -> path, s_new -> name);
				}
				else{
					/* TODO: check permission */
					UNIX_rename_file(fnode->path, s_new->name);
				}
			}

			if(s_new -> mode != 0xffffffff && s_old -> mode != s_new -> mode){
				/* only change the permissions */
#ifdef DEBUG
				printf("MODE required to change from %d to %d!\n", s_old -> mode, s_new -> mode);
#endif
				UNIX_change_permissions(fnode->path, s_new -> mode);
			}
			R_p9_obj -> size = 7;
			R_p9_obj -> type = P9_RWSTAT;
			R_p9_obj -> tag = T_p9_obj -> tag;
			/* also gid can be changed but that should be taken care of later */
			destroy_stat(s_old);
			break;
		}//end of scope
		case P9_TFLUSH:
			R_p9_obj -> size = 7;
			R_p9_obj -> tag = T_p9_obj -> tag;
			R_p9_obj -> type = P9_RFLUSH;
			break;
		default:
			break;
	};
}
Example #4
0
File: file.c Project: Elohim/FGmud
array_t *get_dir (const char * path, int flags)
{
    array_t *v;
    int i, count = 0;
#ifndef WIN32
    DIR *dirp;
#endif
    int namelen, do_match = 0;

#ifndef WIN32
#ifdef USE_STRUCT_DIRENT
    struct dirent *de;
#else
    struct direct *de;
#endif
#endif
    struct stat st;
    char *endtemp;
    char temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2];
    char regexppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2];
    char *p;

#ifdef WIN32
    struct _finddata_t FindBuffer;
    long FileHandle, FileCount;
#endif

    if (!path)
        return 0;

    path = check_valid_path(path, current_object, "stat", 0);

    if (path == 0)
        return 0;

    if (strlen(path) < 2) {
        temppath[0] = path[0] ? path[0] : '.';
        temppath[1] = '\000';
        p = temppath;
    } else {
        strncpy(temppath, path, MAX_FNAME_SIZE + MAX_PATH_LEN + 1);
        temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 1] = '\0';

        /*
         * If path ends with '/' or "/." remove it
         */
        if ((p = strrchr(temppath, '/')) == 0)
            p = temppath;
        if (p[0] == '/' && ((p[1] == '.' && p[2] == '\0') || p[1] == '\0'))
            *p = '\0';
    }

    if (stat(temppath, &st) < 0) {
        if (*p == '\0')
            return 0;
        if (p != temppath) {
            strcpy(regexppath, p + 1);
            *p = '\0';
        } else {
            strcpy(regexppath, p);
            strcpy(temppath, ".");
        }
        do_match = 1;
    } else if (*p != '\0' && strcmp(temppath, ".")) {
        if (*p == '/' && *(p + 1) != '\0')
            p++;
        v = allocate_empty_array(1);
        encode_stat(&v->item[0], flags, p, &st);
        return v;
    }
#ifdef WIN32
    FileHandle = -1;
    FileCount = 1;
/*    strcat(temppath, "\\*"); */
    strcat(temppath, "/*");
    if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0;
#else
    if ((dirp = opendir(temppath)) == 0)
        return 0;
#endif

    /*
     * Count files
     */
#ifdef WIN32
    do {
        if (!do_match && (!strcmp(FindBuffer.name, ".") ||
                          !strcmp(FindBuffer.name, ".."))) {
            continue;
        }
        if (do_match && !match_string(regexppath, FindBuffer.name)) {
            continue;
        }
        count++;
        if (count >= max_array_size) {
            break;
        }
    } while (!_findnext(FileHandle, &FindBuffer));
    _findclose(FileHandle);
#else
    for (de = readdir(dirp); de; de = readdir(dirp)) {
#ifdef USE_STRUCT_DIRENT
        namelen = strlen(de->d_name);
#else
        namelen = de->d_namlen;
#endif
        if (!do_match && (strcmp(de->d_name, ".") == 0 ||
                          strcmp(de->d_name, "..") == 0))
            continue;
        if (do_match && !match_string(regexppath, de->d_name))
            continue;
        count++;
        if (count >= max_array_size)
            break;
    }
#endif

    /*
     * Make array and put files on it.
     */
    v = allocate_empty_array(count);
    if (count == 0) {
        /* This is the easy case :-) */
#ifndef WIN32
        closedir(dirp);
#endif
        return v;
    }
#ifdef WIN32
    FileHandle = -1;
    if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0;
    endtemp = temppath + strlen(temppath) - 2;
    *endtemp = 0;
/*    strcat(endtemp++, "\\"); */
    strcat(endtemp++, "/");
    i = 0;
    do {
        if (!do_match && (!strcmp(FindBuffer.name, ".") ||
                          !strcmp(FindBuffer.name, ".."))) continue;
        if (do_match && !match_string(regexppath, FindBuffer.name)) continue;
        if (flags == -1) {
            strcpy(endtemp, FindBuffer.name);
            stat(temppath, &st);
        }
        encode_stat(&v->item[i], flags, FindBuffer.name, &st);
        i++;
    } while (!_findnext(FileHandle, &FindBuffer));
    _findclose(FileHandle);
#else                           /* WIN32 */
    rewinddir(dirp);
    endtemp = temppath + strlen(temppath);

    strcat(endtemp++, "/");

    for (i = 0, de = readdir(dirp); i < count; de = readdir(dirp)) {
#ifdef USE_STRUCT_DIRENT
        namelen = strlen(de->d_name);
#else
        namelen = de->d_namlen;
#endif
        if (!do_match && (strcmp(de->d_name, ".") == 0 ||
                          strcmp(de->d_name, "..") == 0))
            continue;
        if (do_match && !match_string(regexppath, de->d_name))
            continue;
        de->d_name[namelen] = '\0';
        if (flags == -1) {
            /*
             * We'll have to .... sigh.... stat() the file to get some add'tl
             * info.
             */
            strcpy(endtemp, de->d_name);
            stat(temppath, &st);/* We assume it works. */
        }
        encode_stat(&v->item[i], flags, de->d_name, &st);
        i++;
    }
    closedir(dirp);
#endif                          /* OS2 */

    /* Sort the names. */
    qsort((void *) v->item, count, sizeof v->item[0],
          (flags == -1) ? parrcmp : pstrcmp);
    return v;
}
Example #5
0
int send_file(FF_PKT *ff, bool top_level, struct config *conf, struct cntr *p1cntr)
{
   char msg[128]="";
   char attribs[MAXSTRING];

   if(!file_is_included(conf->incexcdir, conf->iecount,
	conf->incext, conf->incount,
	conf->excext, conf->excount,
	conf->increg, conf->ircount,
	conf->excreg, conf->ercount,
	ff->fname, top_level)) return 0;
#ifdef HAVE_WIN32
// Useful Windows attributes debug
/*
	printf("\n%llu", ff->winattr);
	printf("\n%s\n", ff->fname);
if(ff->winattr & FILE_ATTRIBUTE_READONLY) printf("readonly\n");
if(ff->winattr & FILE_ATTRIBUTE_HIDDEN) printf("hidden\n");
if(ff->winattr & FILE_ATTRIBUTE_SYSTEM) printf("system\n");
if(ff->winattr & FILE_ATTRIBUTE_DIRECTORY) printf("directory\n");
if(ff->winattr & FILE_ATTRIBUTE_ARCHIVE) printf("archive\n");
if(ff->winattr & FILE_ATTRIBUTE_DEVICE) printf("device\n");
if(ff->winattr & FILE_ATTRIBUTE_NORMAL) printf("normal\n");
if(ff->winattr & FILE_ATTRIBUTE_TEMPORARY) printf("temporary\n");
if(ff->winattr & FILE_ATTRIBUTE_SPARSE_FILE) printf("sparse\n");
if(ff->winattr & FILE_ATTRIBUTE_REPARSE_POINT) printf("reparse\n");
if(ff->winattr & FILE_ATTRIBUTE_COMPRESSED) printf("compressed\n");
if(ff->winattr & FILE_ATTRIBUTE_OFFLINE) printf("offline\n");
if(ff->winattr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) printf("notcont\n");
if(ff->winattr & FILE_ATTRIBUTE_ENCRYPTED) printf("encrypted\n");
if(ff->winattr & FILE_ATTRIBUTE_VIRTUAL) printf("virtual\n");
*/
	if(ff->winattr & FILE_ATTRIBUTE_ENCRYPTED)
	{
//		if(ff->type!=FT_DIREND)
//			logw(p1cntr, "EFS not yet supported: %s", ff->fname);
//		return 0;

		if(ff->type==FT_REGE
		  || ff->type==FT_REG
		  || ff->type==FT_DIRBEGIN)
		{
			encode_stat(attribs,
				&ff->statp, ff->winattr, conf->compression);
			if(async_write_str(CMD_STAT, attribs)
			  || async_write_str(CMD_EFS_FILE, ff->fname))
				return -1;
			do_filecounter(p1cntr, CMD_EFS_FILE, 1);
			if(ff->type==FT_REG)
				do_filecounter_bytes(p1cntr,
					(unsigned long long)ff->statp.st_size);
			return 0;
		}
		else if(ff->type==FT_DIREND)
			return 0;
		else
		{
			// Hopefully, here is never reached.
			logw(p1cntr, "EFS type %d not yet supported: %s",
				ff->type,
				ff->fname);
			return 0;
		}
	}
#endif

   //logp("%d: %s\n", ff->type, ff->fname);

   switch (ff->type) {
   case FT_LNKSAVED:
        //printf("Lnka: %s -> %s\n", ff->fname, ff->link);
   	encode_stat(attribs, &ff->statp, ff->winattr, conf->compression);
	if(async_write_str(CMD_STAT, attribs)
	  || async_write_str(CMD_HARD_LINK, ff->fname)
	  || async_write_str(CMD_HARD_LINK, ff->link))
		return -1;
	do_filecounter(p1cntr, CMD_HARD_LINK, 1);
	// At least FreeBSD 8.2 can have different xattrs on hard links.
	if(maybe_send_extrameta(ff->fname, CMD_HARD_LINK, attribs, p1cntr))
		return -1;
      break;
   case FT_FIFO:
   case FT_REGE:
   case FT_REG:
      encode_stat(attribs, &ff->statp, ff->winattr,
		in_exclude_comp(conf->excom, conf->excmcount,
			ff->fname, conf->compression));
      if(async_write_str(CMD_STAT, attribs)
	|| async_write_str(filesymbol, ff->fname))
		return -1;
      do_filecounter(p1cntr, filesymbol, 1);
      if(ff->type==FT_REG)
	do_filecounter_bytes(p1cntr, (unsigned long long)ff->statp.st_size);
      if(maybe_send_extrameta(ff->fname, filesymbol, attribs, p1cntr))
		return -1;
      break;
   case FT_LNK:
	//printf("link: %s -> %s\n", ff->fname, ff->link);
   	encode_stat(attribs, &ff->statp, ff->winattr, conf->compression);
	if(async_write_str(CMD_STAT, attribs)
	  || async_write_str(CMD_SOFT_LINK, ff->fname)
	  || async_write_str(CMD_SOFT_LINK, ff->link))
		return -1;
	do_filecounter(p1cntr, CMD_SOFT_LINK, 1);
        if(maybe_send_extrameta(ff->fname, CMD_SOFT_LINK, attribs, p1cntr))
		return -1;
      break;
   case FT_DIREND:
      return 0;
   case FT_NOFSCHG:
   case FT_DIRBEGIN:
   case FT_REPARSE:
   case FT_JUNCTION:
	{
         char errmsg[100] = "";
         if (ff->type == FT_NOFSCHG)
            snprintf(errmsg, sizeof(errmsg), _("\t[will not descend: file system change not allowed]"));
	 if(*errmsg)
	 {
		snprintf(msg, sizeof(msg),
			"%s%s%s\n", "Dir: ", ff->fname, errmsg);
		logw(p1cntr, "%s", msg);
	 }
	 else
	 {
		encode_stat(attribs,
			&ff->statp, ff->winattr, conf->compression);
	      	if(async_write_str(CMD_STAT, attribs)) return -1;
#if defined(WIN32_VSS)
		if(async_write_str(filesymbol, ff->fname)) return -1;
		do_filecounter(p1cntr, filesymbol, 1);
#else
		if(async_write_str(CMD_DIRECTORY, ff->fname)) return -1;
		do_filecounter(p1cntr, CMD_DIRECTORY, 1);
        	if(maybe_send_extrameta(ff->fname, CMD_DIRECTORY,
			attribs, p1cntr)) return -1;
#endif
	 }
	}
      break;
   case FT_SPEC: // special file - fifo, socket, device node...
      encode_stat(attribs, &ff->statp, ff->winattr, conf->compression);
      if(async_write_str(CMD_STAT, attribs)
	  || async_write_str(CMD_SPECIAL, ff->fname))
		return -1;
      do_filecounter(p1cntr, CMD_SPECIAL, 1);
      if(maybe_send_extrameta(ff->fname, CMD_SPECIAL, attribs, p1cntr))
		return -1;
      break;
   case FT_NOACCESS:
      logw(p1cntr, _("Err: Could not access %s: %s"), ff->fname, strerror(errno));
      break;
   case FT_NOFOLLOW:
      logw(p1cntr, _("Err: Could not follow ff->link %s: %s"), ff->fname, strerror(errno));
      break;
   case FT_NOSTAT:
      logw(p1cntr, _("Err: Could not stat %s: %s"), ff->fname, strerror(errno));
      break;
   case FT_NOCHG:
      logw(p1cntr, _("Skip: File not saved. No change. %s"), ff->fname);
      break;
   case FT_ISARCH:
      logw(p1cntr, _("Err: Attempt to backup archive. Not saved. %s"), ff->fname);
      break;
   case FT_NOOPEN:
      logw(p1cntr, _("Err: Could not open directory %s: %s"), ff->fname, strerror(errno));
      break;
   case FT_RAW:
      logw(p1cntr, _("Err: Raw partition: %s"), ff->fname);
      break;
   default:
      logw(p1cntr, _("Err: Unknown file ff->type %d: %s"), ff->type, ff->fname);
      break;
   }
   return 0;
}
Example #6
0
static int do_backup_phase2_client(struct config *conf, int resume, struct cntr *cntr)
{
    int ret=0;
    int quit=0;
    char cmd;
    char *buf=NULL;
    size_t len=0;
    char attribs[MAXSTRING];

    struct sbuf sb;

    init_sbuf(&sb);

    if(!resume)
    {
        // Only do this bit if the server did not tell us to resume.
        if(async_write_str(CMD_GEN, "backupphase2")
                || async_read_expect(CMD_GEN, "ok"))
            return -1;
    }

    while(!quit)
    {
        if(async_read(&cmd, &buf, &len))
        {
            ret=-1;
            quit++;
        }
        else if(buf)
        {
            //logp("now: %c:%s\n", cmd, buf);
            if(cmd==CMD_DATAPTH)
            {
                sb.datapth=buf;
                buf=NULL;
                continue;
            }
            else if(cmd==CMD_STAT)
            {
                // Ignore the stat data - we will fill it
                // in again. Some time may have passed by now,
                // and it is best to make it as fresh as
                // possible.
                free(buf);
                buf=NULL;
                continue;
            }
            else if(cmd==CMD_FILE
                    || cmd==CMD_ENC_FILE
                    || cmd==CMD_METADATA
                    || cmd==CMD_ENC_METADATA
                    || cmd==CMD_EFS_FILE)
            {
                int forget=0;
                int64_t winattr=0;
                struct stat statbuf;
                char *extrameta=NULL;
                size_t elen=0;
                unsigned long long bytes=0;
                BFILE bfd;
                FILE *fp=NULL;

                sb.path=buf;
                buf=NULL;

#ifdef HAVE_WIN32
                if(win32_lstat(sb.path, &statbuf, &winattr))
#else
                if(lstat(sb.path, &statbuf))
#endif
                {
                    logw(cntr, "Path has vanished: %s", sb.path);
                    if(forget_file(&sb, cmd, cntr))
                    {
                        ret=-1;
                        quit++;
                    }
                    free_sbuf(&sb);
                    continue;
                }

                if(conf->min_file_size
                        && statbuf.st_size<(boffset_t)conf->min_file_size)
                {
                    logw(cntr, "File size decreased below min_file_size after initial scan: %s", sb.path);
                    forget++;
                }
                else if(conf->max_file_size
                        && statbuf.st_size>(boffset_t)conf->max_file_size)
                {
                    logw(cntr, "File size increased above max_file_size after initial scan: %s", sb.path);
                    forget++;
                }

                if(!forget)
                {
                    encode_stat(attribs, &statbuf, winattr);
                    if(open_file_for_send(&bfd, &fp,
                                          sb.path, winattr, cntr))
                        forget++;
                }

                if(forget)
                {
                    if(forget_file(&sb, cmd, cntr))
                    {
                        ret=-1;
                        quit++;
                    }
                    free_sbuf(&sb);
                    continue;
                }

                if(cmd==CMD_METADATA
                        || cmd==CMD_ENC_METADATA)
                {
                    if(get_extrameta(sb.path,
                                     &statbuf, &extrameta, &elen,
                                     cntr))
                    {
                        logw(cntr, "Meta data error for %s", sb.path);
                        free_sbuf(&sb);
                        close_file_for_send(&bfd, &fp);
                        continue;
                    }
                    if(!extrameta)
                    {
                        logw(cntr, "No meta data after all: %s", sb.path);
                        free_sbuf(&sb);
                        close_file_for_send(&bfd, &fp);
                        continue;
                    }
                }

                if(cmd==CMD_FILE && sb.datapth)
                {
                    unsigned long long sentbytes=0;
                    // Need to do sig/delta stuff.
                    if(async_write_str(CMD_DATAPTH, sb.datapth)
                            || async_write_str(CMD_STAT, attribs)
                            || async_write_str(CMD_FILE, sb.path)
                            || load_signature_and_send_delta(
                                &bfd, fp,
                                &bytes, &sentbytes, cntr))
                    {
                        logp("error in sig/delta for %s (%s)\n", sb.path, sb.datapth);
                        ret=-1;
                        quit++;
                    }
                    else
                    {
                        do_filecounter(cntr, CMD_FILE_CHANGED, 1);
                        do_filecounter_bytes(cntr, bytes);
                        do_filecounter_sentbytes(cntr, sentbytes);
                    }
                }
                else
                {
                    //logp("need to send whole file: %s\n",
                    //	sb.path);
                    // send the whole file.
                    if(async_write_str(CMD_STAT, attribs)
                            || async_write_str(cmd, sb.path)
                            || send_whole_file_w(cmd, sb.path,
                                                 NULL, 0, &bytes,
                                                 conf->encryption_password,
                                                 cntr, conf->compression,
                                                 &bfd, fp,
                                                 extrameta, elen))
                    {
                        ret=-1;
                        quit++;
                    }
                    else
                    {
                        do_filecounter(cntr, cmd, 1);
                        do_filecounter_bytes(cntr, bytes);
                        do_filecounter_sentbytes(cntr, bytes);
                    }
                }
                close_file_for_send(&bfd, &fp);
                free_sbuf(&sb);
                if(extrameta) free(extrameta);
            }
            else if(cmd==CMD_WARNING)
            {
                do_filecounter(cntr, cmd, 0);
                free(buf);
                buf=NULL;
            }
            else if(cmd==CMD_GEN && !strcmp(buf, "backupphase2end"))
            {
                if(async_write_str(CMD_GEN, "okbackupphase2end"))
                    ret=-1;
                quit++;
            }
            else
            {
                logp("unexpected cmd from server: %c %s\n",
                     cmd, buf);
                ret=-1;
                quit++;
                free(buf);
                buf=NULL;
            }
        }
    }
    return ret;
}
Example #7
0
/*
 * Called here by find() for each file.
 *
 *  Find the file, compute the MD5 or SHA1 and send it back to the Director
 */
static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
{
   POOL_MEM attribs(PM_NAME),
            attribsEx(PM_NAME);
   int digest_stream = STREAM_NONE;
   int status;
   DIGEST *digest = NULL;
   BSOCK *dir;

   if (job_canceled(jcr)) {
      return 0;
   }

   dir = jcr->dir_bsock;
   jcr->num_files_examined++;         /* bump total file count */

   switch (ff_pkt->type) {
   case FT_LNKSAVED:                  /* Hard linked, file already saved */
      Dmsg2(30, "FT_LNKSAVED saving: %s => %s\n", ff_pkt->fname, ff_pkt->link);
      break;
   case FT_REGE:
      Dmsg1(30, "FT_REGE saving: %s\n", ff_pkt->fname);
      break;
   case FT_REG:
      Dmsg1(30, "FT_REG saving: %s\n", ff_pkt->fname);
      break;
   case FT_LNK:
      Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
      break;
   case FT_DIRBEGIN:
      jcr->num_files_examined--;      /* correct file count */
      return 1;                       /* ignored */
   case FT_REPARSE:
   case FT_JUNCTION:
   case FT_DIREND:
      Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname);
      break;
   case FT_SPEC:
      Dmsg1(30, "FT_SPEC saving: %s\n", ff_pkt->fname);
      break;
   case FT_RAW:
      Dmsg1(30, "FT_RAW saving: %s\n", ff_pkt->fname);
      break;
   case FT_FIFO:
      Dmsg1(30, "FT_FIFO saving: %s\n", ff_pkt->fname);
      break;
   case FT_NOACCESS: {
      berrno be;
      be.set_errno(ff_pkt->ff_errno);
      Jmsg(jcr, M_NOTSAVED, 1, _("     Could not access %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror());
      jcr->JobErrors++;
      return 1;
   }
   case FT_NOFOLLOW: {
      berrno be;
      be.set_errno(ff_pkt->ff_errno);
      Jmsg(jcr, M_NOTSAVED, 1, _("     Could not follow link %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror());
      jcr->JobErrors++;
      return 1;
   }
   case FT_NOSTAT: {
      berrno be;
      be.set_errno(ff_pkt->ff_errno);
      Jmsg(jcr, M_NOTSAVED, 1, _("     Could not stat %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror());
      jcr->JobErrors++;
      return 1;
   }
   case FT_DIRNOCHG:
   case FT_NOCHG:
      Jmsg(jcr, M_SKIPPED, 1, _("     Unchanged file skipped: %s\n"), ff_pkt->fname);
      return 1;
   case FT_ISARCH:
      Jmsg(jcr, M_SKIPPED, 1, _("     Archive file skipped: %s\n"), ff_pkt->fname);
      return 1;
   case FT_NORECURSE:
      Jmsg(jcr, M_SKIPPED, 1, _("     Recursion turned off. Directory skipped: %s\n"), ff_pkt->fname);
      ff_pkt->type = FT_DIREND;     /* directory entry was backed up */
      break;
   case FT_NOFSCHG:
      Jmsg(jcr, M_SKIPPED, 1, _("     File system change prohibited. Directory skipped: %s\n"), ff_pkt->fname);
      return 1;
   case FT_PLUGIN_CONFIG:
   case FT_RESTORE_FIRST:
      return 1;                       /* silently skip */
   case FT_NOOPEN: {
      berrno be;
      be.set_errno(ff_pkt->ff_errno);
      Jmsg(jcr, M_NOTSAVED, 1, _("     Could not open directory %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror());
      jcr->JobErrors++;
      return 1;
   }
   default:
      Jmsg(jcr, M_NOTSAVED, 0, _("     Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname);
      jcr->JobErrors++;
      return 1;
   }

   /* Encode attributes and possibly extend them */
   encode_stat(attribs.c_str(), &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, 0);
   encode_attribsEx(jcr, attribsEx.c_str(), ff_pkt);

   jcr->lock();
   jcr->JobFiles++;                  /* increment number of files sent */
   pm_strcpy(jcr->last_fname, ff_pkt->fname);
   jcr->unlock();

   /*
    * Send file attributes to Director
    *   File_index
    *   Stream
    *   Verify Options
    *   Filename (full path)
    *   Encoded attributes
    *   Link name (if type==FT_LNK)
    * For a directory, link is the same as fname, but with trailing
    * slash. For a linked file, link is the link.
    */
   /* Send file attributes to Director (note different format than for Storage) */
   Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname);
   if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
      status = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
                          STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
                          0, attribs.c_str(), 0, ff_pkt->link, 0);
   } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE ||
              ff_pkt->type == FT_JUNCTION) {
      /* Here link is the canonical filename (i.e. with trailing slash) */
      status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles,
                          STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link,
                          0, attribs.c_str(), 0, 0);
   } else {
      status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles,
                          STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
                          0, attribs.c_str(), 0, 0);
   }
   Dmsg2(20, "filed>dir: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
   if (!status) {
      Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
      return 0;
   }

   /*
    * The remainder of the function is all about getting the checksum.
    * First we initialise, then we read files, other streams and Finder Info.
    */
   if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
            ff_pkt->flags & (FO_MD5|FO_SHA1|FO_SHA256|FO_SHA512))) {
      /*
       * Create our digest context. If this fails, the digest will be set to NULL
       * and not used.
       */
      if (ff_pkt->flags & FO_MD5) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
         digest_stream = STREAM_MD5_DIGEST;

      } else if (ff_pkt->flags & FO_SHA1) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
         digest_stream = STREAM_SHA1_DIGEST;

      } else if (ff_pkt->flags & FO_SHA256) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
         digest_stream = STREAM_SHA256_DIGEST;

      } else if (ff_pkt->flags & FO_SHA512) {
         digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
         digest_stream = STREAM_SHA512_DIGEST;
      }

      /* Did digest initialization fail? */
      if (digest_stream != STREAM_NONE && digest == NULL) {
         Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
              stream_to_ascii(digest_stream));
      }

      /* compute MD5 or SHA1 hash */
      if (digest) {
         char md[CRYPTO_DIGEST_MAX_SIZE];
         uint32_t size;

         size = sizeof(md);

         if (digest_file(jcr, ff_pkt, digest) != 0) {
            jcr->JobErrors++;
            goto good_rtn;
         }

         if (crypto_digest_finalize(digest, (uint8_t *)md, &size)) {
            char *digest_buf;
            const char *digest_name;

            digest_buf = (char *)malloc(BASE64_SIZE(size));
            digest_name = crypto_digest_name(digest);

            bin_to_base64(digest_buf, BASE64_SIZE(size), md, size, true);
            Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, digest_name, digest_buf);
            dir->fsend("%d %d %s *%s-%d*", jcr->JobFiles, digest_stream, digest_buf,
                       digest_name, jcr->JobFiles);
            Dmsg3(20, "filed>dir: %s len=%d: msg=%s\n", digest_name,
                  dir->msglen, dir->msg);

            free(digest_buf);
         }
      }
   }

good_rtn:
   if (digest) {
      crypto_digest_free(digest);
   }
   return 1;
}
Example #8
0
void test_base64(void **state) {
   (void) state; /* unused */


/*
 * Test the base64 routines by encoding and decoding
 * lstat() packets.
 */

   char where[500];
   int i;
   char *fname;
   struct stat statp;
   struct stat statn;
   int debug_level = 0;
   char *p;
   int32_t j;
   time_t t = 1028712799;


   fname = BINARYNAME;
   base64_init();
   if (lstat(fname, &statp) < 0) {
      berrno be;
      printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno));
   }
   encode_stat(where, &statp, sizeof(statp), 0, 0);

   //printf("Encoded stat=%s\n", where);

#ifdef xxx
   p = where;
   p += to_base64((int64_t)(statp.st_atime), p);
   *p++ = ' ';
   p += to_base64((int64_t)t, p);
   printf("%s %s\n", fname, where);

   printf("%s %lld\n", "st_dev", (int64_t)statp.st_dev);
   printf("%s %lld\n", "st_ino", (int64_t)statp.st_ino);
   printf("%s %lld\n", "st_mode", (int64_t)statp.st_mode);
   printf("%s %lld\n", "st_nlink", (int64_t)statp.st_nlink);
   printf("%s %lld\n", "st_uid", (int64_t)statp.st_uid);
   printf("%s %lld\n", "st_gid", (int64_t)statp.st_gid);
   printf("%s %lld\n", "st_rdev", (int64_t)statp.st_rdev);
   printf("%s %lld\n", "st_size", (int64_t)statp.st_size);
   printf("%s %lld\n", "st_blksize", (int64_t)statp.st_blksize);
   printf("%s %lld\n", "st_blocks", (int64_t)statp.st_blocks);
   printf("%s %lld\n", "st_atime", (int64_t)statp.st_atime);
   printf("%s %lld\n", "st_mtime", (int64_t)statp.st_mtime);
   printf("%s %lld\n", "st_ctime", (int64_t)statp.st_ctime);
#endif

   //printf("%s: len=%d val=%s\n", fname, strlen(where), where);

   decode_stat(where, &statn, sizeof(statn), &j);

   assert_false(statp.st_dev != statn.st_dev ||
         statp.st_ino != statn.st_ino ||
         statp.st_mode != statn.st_mode ||
         statp.st_nlink != statn.st_nlink ||
         statp.st_uid != statn.st_uid ||
         statp.st_gid != statn.st_gid ||
         statp.st_rdev != statn.st_rdev ||
         statp.st_size != statn.st_size ||
         statp.st_blksize != statn.st_blksize ||
         statp.st_blocks != statn.st_blocks ||
         statp.st_atime != statn.st_atime ||
         statp.st_mtime != statn.st_mtime ||
         statp.st_ctime != statn.st_ctime);

   /*
      {  printf("%s: %s\n", fname, where);
      encode_stat(where, &statn, sizeof(statn), 0, 0);
      printf("%s: %s\n", fname, where);
      printf("NOT EQAL\n");
      }
      */


//printf("%d files examined\n", i);

to_base64(UINT32_MAX, where);
//printf("UINT32_MAX=%s\n", where);











int xx = 0;
int len;
char buf[100];
char junk[100];
//   int i;

#ifdef xxxx
   for (i=0; i < 1000; i++) {
      bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
      printf("xx=%s\n", buf);
      xx++;
   }
#endif
   junk[0] = 0xFF;
   for (i=1; i<100; i++) {
      junk[i] = junk[i-1]-1;
   }
   len = bin_to_base64(buf, sizeof(buf), junk, 16, true);
   //printf("len=%d junk=%s\n", len, buf);

   strcpy(junk, "This is a sample string");
   len = bin_to_base64(buf, sizeof(buf), junk, strlen(junk), true);
   buf[len] = 0;
   base64_to_bin(junk, sizeof(junk), buf, len);
   //printf("buf=<%s>\n", junk);

}
Example #9
0
bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
{
   BSOCK *sd = jcr->store_bsock;
   char attribs[MAXSTRING];
   char attribsEx[MAXSTRING];
   int attr_stream;
   int stat;
#ifdef FD_NO_SEND_TEST
   return true;
#endif

   Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
   /* Find what data stream we will use, then encode the attributes */
   if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
      /* This should not happen */
      Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
      return false;
   }
   encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream);

   /* Now possibly extend the attributes */
   attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);

   Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);

   jcr->lock();
   jcr->JobFiles++;                    /* increment number of files sent */
   ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
   pm_strcpy(jcr->last_fname, ff_pkt->fname);
   jcr->unlock();

   /*
    * Send Attributes header to Storage daemon
    *    <file-index> <stream> <info>
    */
   if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
            sd->bstrerror());
      return false;
   }
   Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);

   /*
    * Send file attributes to Storage daemon
    *   File_index
    *   File type
    *   Filename (full path)
    *   Encoded attributes
    *   Link name (if type==FT_LNK or FT_LNKSAVED)
    *   Encoded extended-attributes (for Win32)
    *
    * For a directory, link is the same as fname, but with trailing
    * slash. For a linked file, link is the link.
    */
   if (ff_pkt->type != FT_DELETED) { /* already stripped */
      strip_path(ff_pkt);
   }
   if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
      Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
      stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
               ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
               attribsEx, 0);
   } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
      /* Here link is the canonical filename (i.e. with trailing slash) */
      stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
               ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
   } else {
      stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
               ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
   }
   if (ff_pkt->type != FT_DELETED) {
      unstrip_path(ff_pkt);
   }

   Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
   if (!stat) {
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
            sd->bstrerror());
      return false;
   }
   sd->signal(BNET_EOD);            /* indicate end of attributes data */
   return true;
}