예제 #1
0
/*** (a)
     get those softlinks that points to a directory 
     this is to deal with the following scenario
     previous structure
         dir_path  (a directory)
         db        (a directory)

     newly updated structure on master
         dir_path -> db
         db

     rsync --dry-run generates
        dir_path -> db                      [a link is done on target]
        deleting dir_path/sub/filename1     [wrong file gets removed ]
	deleting dir_path/sub/filename2...

     file_operations.c does this when dir_path -> db is due
        delete dir_path (rm -rf)
        make the softlink
     But then the following delete will have undesired deletion.

     ------------------------------------------------------------

     (b)
     t0     name -> xyz         name -> xyz (target)
     t1     name/               name -> xyz

     rsync generates
         name/               update_directory() won't have effect
         name/f1             delivered to wrong place
	 name/f2
	 deleting name       too late
	 ** the deletion should be done before not after.
            For now, I will fail this code for this situation.
     
***/
void get_dir_softlinks(char *filename, char * basedir) {
  FILE * fd;
  char line[PATH_MAX];
  struct stat st;

  if ((fd = fopen(filename, "r")) == NULL) {
    fprintf(stderr, "Cannot open file -- %s \n", filename);
    exit(-1);
  }

  while (1) { /* for each line in the file */
    char *pc;
    char fn[PATH_MAX];

    if (fgets(line, PATH_MAX, fd)==NULL) break;
    strip(line);
    if (strlen(line) == 0) continue; /* skip blank line */

    /* the softlink case is indicated by -> */
    pc= strstr(line, " -> ");
    if (pc) { /* it is a softlink */
      *pc = '\0';
      /* check if it is a directory */
      sprintf(fn, "%s/%s", basedir, line);

      /* check if the link-target is a directory */    
      if (stat(fn, &st)<0) continue; /* We skip this bad entry - no longer exist */
      
      if (S_ISDIR(st.st_mode)) {
	append_string_list(line, &softlink_list);
      }
    } else { /* not a softlink --> find if it is a directory */
      /* find a line without ' ' and with trailing '/' */     
      pc = strstr(line, " "); /* the first space */
      if (!pc) {
	char * plast = &line[0] + strlen(line) - 1;
	if (*plast == '/') {
	  append_string_list(line, &newdir_list);
	}
      }
    }
  }

  fclose(fd);  
}
예제 #2
0
파일: entrygroup.c 프로젝트: EBone/Faust
int avahi_entry_group_update_service_txt_strlst(
    AvahiEntryGroup *group,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiPublishFlags flags,
    const char *name,
    const char *type,
    const char *domain,
    AvahiStringList *txt) {

    DBusMessage *message = NULL, *reply = NULL;
    int r = AVAHI_OK;
    DBusError error;
    AvahiClient *client;
    int32_t i_interface, i_protocol;
    uint32_t u_flags;

    assert(group);
    assert(name);
    assert(type);

    client = group->client;

    if (!group->path || !avahi_client_is_connected(group->client))
        return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);

    if (!domain)
        domain = "";

    dbus_error_init(&error);

    if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "UpdateServiceTxt"))) {
        r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    i_interface = (int32_t) interface;
    i_protocol = (int32_t) protocol;
    u_flags = (uint32_t) flags;

    if (!dbus_message_append_args(
            message,
            DBUS_TYPE_INT32, &i_interface,
            DBUS_TYPE_INT32, &i_protocol,
            DBUS_TYPE_UINT32, &u_flags,
            DBUS_TYPE_STRING, &name,
            DBUS_TYPE_STRING, &type,
            DBUS_TYPE_STRING, &domain,
            DBUS_TYPE_INVALID) ||
        append_string_list(message, txt) < 0) {
        r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) ||
        dbus_error_is_set (&error)) {
        r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) ||
        dbus_error_is_set (&error)) {
        r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    dbus_message_unref(message);
    dbus_message_unref(reply);

    return AVAHI_OK;

fail:

    if (dbus_error_is_set(&error)) {
        r = avahi_client_set_dbus_error(client, &error);
        dbus_error_free(&error);
    }

    if (message)
        dbus_message_unref(message);

    if (reply)
        dbus_message_unref(reply);

    return r;
}
예제 #3
0
int main(int argc, char * argv[])
{
  char * filename;
  char * basedir;
  FILE *fd;
  char line[PATH_MAX];

  if (argc < 3) {
    fprintf(stderr, "Usage: trFilelist synclist_filename basedir\n");
    exit(-1);
  }

  filename = argv[1];
  basedir = argv[2];

  init_string_list(&file_list, 10);
  init_uint_list(&ino_list, 10);
  init_string_list(&dir_list, 100);
  init_string_list(&softlink_list, 10);
  init_string_list(&newdir_list, 100);

  get_dir_softlinks(filename, basedir);
  
  if ((fd = fopen(filename, "r")) == NULL) {
    fprintf(stderr, "Cannot open file -- %s \n", filename);
    return -1;
  }

  while (1) { /* for each line in the file */
    char *pc;
    char fn[PATH_MAX];
    struct stat st;
    int newdir_flag;

    if (fgets(line, PATH_MAX, fd)==NULL) break;
    strip(line);
    if (strlen(line) == 0) continue; /* skip blank line */
    if (strcmp(line, ".")==0) continue;
    if (strcmp(line, "./")==0) continue;

    /* first we look for deleting entry */
    if (strncmp(line, "deleting ", 9)==0) {
      /* deleting (directory) file_path */
      char * p1, *p2, *pf;

      p1 = strstr(line, " "); /* the first space */
      p2 = strstr(p1+1, " "); /* deleting directory filepath * 20070912 this is old */ 
      pf = (p2) ? p2+1 : p1+1;/* it's always p1+1 */

      newdir_flag = has_newdir(pf, &newdir_list);

      if ((has_sub_string(pf, &softlink_list)<0) && newdir_flag<0) { 
	/* see comments above get_dir_softlinks() */
	printf("deleting %s\n", pf);
      } else if (newdir_flag>=0) { /* temporary action */
	/*** we can simply skip this block later. 20070912 ***/	   
	/***/
	fprintf(stderr, "CRITICAL ERROR: An old softlink has been changed to a directory!\n");
	fprintf(stderr, "                For now, we crash this code for human intervention\n");
	fprintf(stderr, "                line= %s\n", line);
	exit(-1);
	/***/
      }

      continue;
    }
    
    /* the softlink case is indicated by -> */
    pc= strstr(line, " -> ");
    if (pc) {
      *pc = '\0';
      output_subs(line);
      printf("%s\n", line);
      continue;
    }

    /* if rsync's -H is turned on, the output may contain
       file => tar_hardlink_file (relative address)
    */
    pc= strstr(line, " => ");
    if (pc) {
      *pc = '\0';
      output_subs(line);
      printf("%s %s\n", line, pc+4);
      continue;
    }

    /* the rest of the entries should be valid paths */
    sprintf(fn, "%s/%s", basedir, line);    
    if (lstat(fn, &st)<0) continue; /* We skip this bad entry - 
				       (1) the header and tail lines
				       (2) perhaps the file no longer exists */

    /* is this a hardlink? */
    if (st.st_nlink > 1) {
      int index;
      output_subs(line);
      if ((index = find_unit((unsigned int)st.st_ino, &ino_list))<0) { 
	append_uint_list((unsigned int)st.st_ino, &ino_list);
	append_string_list(line, &file_list); /* relative path */
	printf("%s\n", line);
      } else {
	printf("%s %s\n", line, file_list.str[index]);
      }
      continue;
    }

    /* all others */
    output_subs(line);
    printf("%s\n", line);
  } /* end of one line */

  fclose(fd);
  return 0;
}