Ejemplo n.º 1
0
//--------------------------------------------------------------------------
// 0 - run uunp interactively
// 1 - run without questions
// 2 - run manual reconstruction
void idaapi run(int arg)
{
  if ( arg == 2 )
  {
    area_t impdir = area_t(0, 0);
    ea_t oep;

    netnode n;

    // Settings never stored before?
    if ( n.create("$ uunp") )
    {
      // Populate default values
      oep = get_screen_ea();
      segment_t *s = getseg(oep);
      if ( s != NULL )
      {
        oep_area.startEA = s->startEA;
        oep_area.endEA = s->endEA;
      }
    }
    else
    {
      // Restore previous settings
      oep              = n.altval(0);
      oep_area.startEA = n.altval(1);
      oep_area.endEA   = n.altval(2);
      impdir.startEA   = n.altval(3);
      impdir.endEA     = n.altval(4);
    }
    if ( !AskUsingForm_c(
      "Reconstruction parameters\n"
      "\n"
      "  <~O~riginal entrypoint:N:128:32::>\n"
      "  <Code ~s~tart address:N:128:32::>\n"
      "  <Code ~e~nd address  :N:128:32::>\n"
      "\n"
      "  <IAT s~t~art address:N:128:32::>\n"
      "  <IAT e~n~d address:N:128:32::>\n"
      "\n",
      &oep,
      &oep_area.startEA, &oep_area.endEA,
      &impdir.startEA, &impdir.endEA) )
    {
      // Cancelled?
      return;
    }

    // Invalid settings?
    if ( impdir.startEA == 0 || impdir.endEA == 0 )
    {
      msg("Invalid import address table boundaries");
      return;
    }

    // Store settings
    n.altset(0, oep);
    n.altset(1, oep_area.startEA);
    n.altset(2, oep_area.endEA);
    n.altset(3, impdir.startEA);
    n.altset(4, impdir.endEA);

    if ( !create_impdir(impdir) )
      return;

    // reanalyze the unpacked code
    do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND);
    auto_make_code(oep);
    noUsed(oep_area.startEA, oep_area.endEA);
    auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL);

    // mark the program's entry point
    move_entry(oep);

    take_memory_snapshot(true);
    return;
  }

  // Determine the original entry point area
  for ( segment_t *s = get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
  {
    if ( s->type != SEG_GRP )
    {
      oep_area = *s;
      break;
    }
  }

  if (    arg == 0
       && askyn_c(0,
              "HIDECANCEL\n"
              "AUTOHIDE REGISTRY\n"
              "Universal PE unpacker\n"
              "\n"
              "IMPORTANT INFORMATION, PLEASE READ CAREFULLY!\n"
              "\n"
              "This plugin will start the program execution and try to suspend it\n"
              "as soon as the packer finishes its work. Since there might be many\n"
              "variations in packers and packing methods, the execution might go out\n"
              "of control. There are many ways how things can go wrong, but since you\n"
              "have the source code of this plugin, you can modify it as you wish.\n"
              "\n"
              "Do you really want to launch the program?\n") <= 0 )
    {
      return;
    }

  success = false;

  set_file_ext(resfile, sizeof(resfile), database_idb, "res");
  if ( arg == 0
    && !AskUsingForm_c(
        "Uunp parameters\n"
        "IDA will suspend the program when the execution reaches\n"
        "the original entry point area. The default values are in\n"
        "this dialog box. Please verify them and correct if you wish.\n"
        "\n"
        "ORIGINAL ENTRY POINT AREA\n"
        "  <~S~tart address:N:128:32::>\n"
        "  <~E~nd address  :N:128:32::>\n"
        "\n"
        "OUTPUT RESOURCE FILE NAME\n"
        "  <~R~esource file:A:256:32::>\n"
        "\n",
        &oep_area.startEA,
        &oep_area.endEA,
        resfile) )
  {
    return;
  }

  if ( !hook_to_notification_point(HT_DBG, callback, NULL) )
  {
    warning("Could not hook to notification point\n");
    return;
  }

  if ( dbg == NULL )
    load_debugger("win32", false);

  // Let's start the debugger
  if ( !run_to(inf.beginEA) )
  {
    warning("Sorry, could not start the process");
    unhook_from_notification_point(HT_DBG, callback, NULL);
  }
}
Ejemplo n.º 2
0
//--------------------------------------------------------------------------
static int idaapi callback(
    void * /*user_data*/,
    int notification_code,
    va_list va)
{
  static int stage = 0;
  static bool is_dll;
  static char needed_file[QMAXPATH];

  switch ( notification_code )
  {
    case dbg_process_start:
    case dbg_process_attach:
      get_input_file_path(needed_file, sizeof(needed_file));
      // no break
    case dbg_library_load:
      if ( stage == 0 )
      {
        const debug_event_t *pev = va_arg(va, const debug_event_t *);
        if ( !strieq(pev->modinfo.name, needed_file) )
          break;
        if ( notification_code == dbg_library_load )
          is_dll = true;
        // remember the current module bounds
        if ( pev->modinfo.rebase_to != BADADDR )
          curmod.startEA = pev->modinfo.rebase_to;
        else
          curmod.startEA = pev->modinfo.base;
        curmod.endEA = curmod.startEA + pev->modinfo.size;
        deb(IDA_DEBUG_PLUGIN, "UUNP: module space %a-%a\n", curmod.startEA, curmod.endEA);
        ++stage;
      }
      break;

    case dbg_library_unload:
      if ( stage != 0 && is_dll )
      {
        const debug_event_t *pev = va_arg(va, const debug_event_t *);
        if ( curmod.startEA == pev->modinfo.base
          || curmod.startEA == pev->modinfo.rebase_to )
        {
          deb(IDA_DEBUG_PLUGIN, "UUNP: unload unpacked module\n");
          if ( stage > 2 )
            enable_step_trace(false);
          stage = 0;
          curmod.startEA = 0;
          curmod.endEA = 0;
          _hide_wait_box();
        }
      }
      break;

    case dbg_run_to:   // Parameters: const debug_event_t *event
      dbg->stopped_at_debug_event(true);
      bp_gpa = get_name_ea(BADADDR, "kernel32_GetProcAddress");
#ifndef __X64__
      if( (LONG)GetVersion() < 0 )  // win9x mode -- use thunk's
      {
        is_9x = true;
        win9x_resolve_gpa_thunk();
      }
#endif
      if ( bp_gpa == BADADDR )
      {
        bring_debugger_to_front();
        warning("Sorry, could not find kernel32.GetProcAddress");
FORCE_STOP:
        stage = 4;  // last stage
        clear_requests_queue();
        request_exit_process();
        run_requests();
        break;
      }
      else if( !my_add_bpt(bp_gpa) )
      {
        bring_debugger_to_front();
        warning("Sorry, can not set bpt to kernel32.GetProcAddress");
        goto FORCE_STOP;
      }
      else
      {
        ++stage;
        set_wait_box("Waiting for a call to GetProcAddress()");
      }
      continue_process();
      break;

    case dbg_bpt:      // A user defined breakpoint was reached.
                       // Parameters: thid_t tid
                       //             ea_t        breakpoint_ea
                       //             int        *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display a breakpoint warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display a breakpoint warning dialog.
                       //               1 - to always display a breakpoint warning dialog.
      {
        thid_t tid = va_arg(va, thid_t); qnotused(tid);
        ea_t ea   = va_arg(va, ea_t);
        //int *warn = va_arg(va, int*);
        if ( stage == 2 )
        {
          if ( ea == bp_gpa )
          {
            regval_t rv;
            if ( get_reg_val(REGNAME_ESP, &rv) )
            {
              ea_t esp = ea_t(rv.ival);
              invalidate_dbgmem_contents(esp, 1024);
              ea_t gpa_caller = getPtr(esp);
              if ( !is_library_entry(gpa_caller) )
              {
                ea_t nameaddr;
                if ( ptrSz == 4 )
                {
                  nameaddr = get_long(esp+8);
                }
                else
                {
                  get_reg_val(REGNAME_ECX, &rv);
                  nameaddr = ea_t(rv.ival);
                }
                invalidate_dbgmem_contents(nameaddr, 1024);
                char name[MAXSTR];
                size_t len = get_max_ascii_length(nameaddr, ASCSTR_C, ALOPT_IGNHEADS);
                name[0] = '\0';
                get_ascii_contents2(nameaddr, len, ASCSTR_C, name, sizeof(name));
                if ( !ignore_win32_api(name) )
                {
                  deb(IDA_DEBUG_PLUGIN, "%a: found a call to GetProcAddress(%s)\n", gpa_caller, name);
                  if ( !my_del_bpt(bp_gpa) || !my_add_bpt(gpa_caller) )
                    error("Can not modify breakpoint");
                }
              }
            }
          }
          else if ( ea == bpt_ea )
          {
            my_del_bpt(ea);
            if ( !is_library_entry(ea) )
            {
              msg("Uunp: reached unpacker code at %a, switching to trace mode\n", ea);
              enable_step_trace(true);
              ++stage;
              uint64 eax;
              if ( get_reg_val(REGNAME_EAX, &eax) )
                an_imported_func = ea_t(eax);
              set_wait_box("Waiting for the unpacker to finish");
            }
            else
            {
              warning("%a: bpt in library code", ea); // how can it be?
              my_add_bpt(bp_gpa);
            }
          }
          // not our bpt? skip it
          else
          {
            // hide the wait box to allow others plugins to properly stop
            _hide_wait_box();
            break;
          }
        }
      }
      // while continue_process() would work here too, request+run is more universal
      // because they do not ignore the request queue
      request_continue_process();
      run_requests();
      break;

    case dbg_trace:    // A step occured (one instruction was executed). This event
                       // notification is only generated if step tracing is enabled.
                       // Parameter:  none
      if ( stage == 3 )
      {
        thid_t tid = va_arg(va, thid_t); qnotused(tid);
        ea_t ip   = va_arg(va, ea_t);

        // ip reached the OEP range?
        if ( oep_area.contains(ip) )
        {
          // stop the trace mode
          enable_step_trace(false);
          msg("Uunp: reached OEP %a\n", ip);
          set_wait_box("Reanalyzing the unpacked code");

          // reanalyze the unpacked code
          do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND);
          auto_make_code(ip); // plan to make code
          noUsed(oep_area.startEA, oep_area.endEA); // plan to reanalyze
          auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL); // plan to analyze
          move_entry(ip); // mark the program's entry point

          _hide_wait_box();

          // inform the user
          bring_debugger_to_front();
          if ( askyn_c(1,
                       "HIDECANCEL\n"
                       "The universal unpacker has finished its work.\n"
                       "Do you want to take a memory snapshot and stop now?\n"
                       "(you can do it yourself if you want)\n") > 0 )
          {
            set_wait_box("Recreating the import table");
            invalidate_dbgmem_config();

            if ( is_9x )
              find_thunked_imports();

            create_impdir();

            set_wait_box("Storing resources to 'resource.res'");
            if ( resfile[0] != '\0' )
              extract_resource(resfile);

            _hide_wait_box();
            if ( take_memory_snapshot(true) )
              goto FORCE_STOP;
          }
          suspend_process();
          unhook_from_notification_point(HT_DBG, callback, NULL);
        }
      }
      break;

    case dbg_process_exit:
      {
        stage = 0;
        // stop the tracing
        _hide_wait_box();
        unhook_from_notification_point(HT_DBG, callback, NULL);
        if ( success )
          jumpto(inf.beginEA, -1);
        else
          tell_about_failure();
      }
      break;

    case dbg_exception:// Parameters: const debug_event_t *event
                       //             int                 *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display an exception warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display an exception warning dialog.
                       //               1 - to always display an exception warning dialog.

    {
//      const debug_event_t *event = va_arg(va, const debug_event_t *);
//      int *warn = va_arg(va, int *);
      // FIXME: handle code which uses SEH to unpack itself
      if ( askyn_c(1,
                   "AUTOHIDE DATABASE\n"
                   "HIDECANCEL\n"
                   "An exception occurred in the program.\n"
                   "UUNP does not support exceptions yet.\n"
                   "The execution has been suspended.\n"
                   "Do you want to continue the unpacking?") <= 0 )
      {
        _hide_wait_box();
        stage = 0;
        enable_step_trace(false); // stop the trace mode
        suspend_process();
      }
      else
      {
        continue_process();
      }
    }
    break;

    case dbg_request_error:
                       // An error occured during the processing of a request.
                       // Parameters: ui_notification_t  failed_command
                       //             dbg_notification_t failed_dbg_notification
      {
        ui_notification_t  failed_cmd = va_arg(va, ui_notification_t);
        dbg_notification_t failed_dbg_notification = va_arg(va, dbg_notification_t);
        _hide_wait_box();
        stage = 0;
        warning("dbg request error: command: %d notification: %d",
                        failed_cmd, failed_dbg_notification);
      }
      break;
  }
  return 0;
}
Ejemplo n.º 3
0
HYPRE_Int hypre_AMGeAgglomerate(HYPRE_Int *i_AE_element, HYPRE_Int *j_AE_element,

                                HYPRE_Int *i_face_face, HYPRE_Int *j_face_face, HYPRE_Int *w_face_face,

                                HYPRE_Int *i_face_element, HYPRE_Int *j_face_element,
                                HYPRE_Int *i_element_face, HYPRE_Int *j_element_face,

                                HYPRE_Int *i_face_to_prefer_weight,
                                HYPRE_Int *i_face_weight,

                                HYPRE_Int num_faces, HYPRE_Int num_elements,
                                HYPRE_Int *num_AEs_pointer)
{

    HYPRE_Int ierr = 0;
    HYPRE_Int i, j, k, l;

    HYPRE_Int face_to_eliminate;
    HYPRE_Int max_weight_old, max_weight;

    HYPRE_Int AE_counter=0, AE_element_counter=0;

    /* HYPRE_Int i_element_face_counter; */

    HYPRE_Int *i_element_to_AE;

    HYPRE_Int *previous, *next, *first;
    HYPRE_Int head, tail, last;

    HYPRE_Int face_max_weight, face_local_max_weight, preferred_weight;

    HYPRE_Int weight, weight_max;

    max_weight = 1;
    for (i=0; i < num_faces; i++)
    {
        weight = 1;
        for (j=i_face_face[i]; j < i_face_face[i+1]; j++)
            weight+= w_face_face[j];
        if (max_weight < weight) max_weight = weight;
    }

    first = hypre_CTAlloc(HYPRE_Int, max_weight+1);



    next = hypre_CTAlloc(HYPRE_Int, num_faces);


    previous = hypre_CTAlloc(HYPRE_Int, num_faces+1);


    tail = num_faces;
    head = -1;

    for (i=0; i < num_faces; i++)
    {
        next[i] = i+1;
        previous[i] = i-1;
    }

    last = num_faces-1;
    previous[tail] = last;

    for (weight=1; weight <= max_weight; weight++)
        first[weight] = tail;

    i_element_to_AE = hypre_CTAlloc(HYPRE_Int, num_elements);

    /*=======================================================================
                       AGGLOMERATION PROCEDURE:
      ======================================================================= */

    for (k=0; k < num_elements; k++)
        i_element_to_AE[k] = -1;

    for (k=0; k < num_faces; k++)
        i_face_weight[k] = 1;


    first[0] = 0;
    first[1] = 0;

    last = previous[tail];
    weight_max = i_face_weight[last];


    k = last;
    face_max_weight = -1;
    while (k!= head)
    {
        if (i_face_to_prefer_weight[k] > -1)
            face_max_weight = k;

        if (face_max_weight > -1) break;

        k=previous[k];
    }


    /* this will be used if the faces have been sorted: *****************
    k = last;
    face_max_weight = -1;
    while (k != head)
      {
        if (i_face_to_prefer_weight[k] > -1)
    face_max_weight = k;


        if (face_max_weight > -1)
    {
      max_weight = i_face_weight[face_max_weight];
      l = face_max_weight;

      while (previous[l] != head)
        {

          if (i_face_weight[previous[l]] < max_weight)
    	break;
          else
    	if (i_face_to_prefer_weight[previous[l]] >
    	    i_face_to_prefer_weight[face_max_weight])
    	  {
    	    l = previous[l];
    	    face_max_weight = l;
    	  }
    	else
    	  l = previous[l];
        }

      break;
    }


        l =previous[k];



        weight = i_face_weight[k];
        last = previous[tail];
        if (last == head)
    weight_max = 0;
        else
    weight_max = i_face_weight[last];


        ierr = remove_entry(weight, &weight_max,
    		  previous, next, first, &last,
    		  head, tail,
    		  k);





        k=l;
      }
      */

    if (face_max_weight == -1)
    {
        hypre_printf("all faces are unacceptable, i.e., no faces to eliminate !\n");

        *num_AEs_pointer = 1;

        i_AE_element[0] = 0;
        for (i=0; i < num_elements; i++)
        {
            i_element_to_AE[i] = 0;
            j_AE_element[i] = i;
        }

        i_AE_element[1] = num_elements;

        return ierr;
    }

    for (k=0; k < num_faces; k++)
        if (i_face_to_prefer_weight[k] > i_face_to_prefer_weight[face_max_weight])
            face_max_weight = k;

    max_weight = i_face_weight[face_max_weight];

    AE_counter=0;
    AE_element_counter=0;


    i_AE_element[AE_counter] = AE_element_counter;

    max_weight_old = -1;

    face_local_max_weight = face_max_weight;

eliminate_face:

    face_to_eliminate = face_local_max_weight;

    max_weight = i_face_weight[face_to_eliminate];

    last = previous[tail];
    if (last == head)
        weight_max = 0;
    else
        weight_max = i_face_weight[last];


    ierr = remove_entry(max_weight, &weight_max,
                        previous, next, first, &last,
                        head, tail,
                        face_to_eliminate);

    i_face_weight[face_to_eliminate] = 0;

    /*----------------------------------------------------------
     *  agglomeration step:
     *
     *  put on AE_element -- list all elements
     *  that share face "face_to_eliminate";
     *----------------------------------------------------------*/

    for (k = i_face_element[face_to_eliminate];
            k < i_face_element[face_to_eliminate+1]; k++)
    {
        /* check if element j_face_element[k] is already on the list: */

        if (j_face_element[k] < num_elements)
        {
            if (i_element_to_AE[j_face_element[k]] == -1)
            {
                j_AE_element[AE_element_counter] = j_face_element[k];
                i_element_to_AE[j_face_element[k]] = AE_counter;
                AE_element_counter++;
            }
        }
    }


    /* local update & search:==================================== */

    for (j=i_face_face[face_to_eliminate];
            j<i_face_face[face_to_eliminate+1]; j++)
        if (i_face_weight[j_face_face[j]] > 0)
        {
            weight = i_face_weight[j_face_face[j]];


            last = previous[tail];
            if (last == head)
                weight_max = 0;
            else
                weight_max = i_face_weight[last];

            ierr = move_entry(weight, &weight_max,
                              previous, next, first, &last,
                              head, tail,
                              j_face_face[j]);

            i_face_weight[j_face_face[j]]+=w_face_face[j];

            weight = i_face_weight[j_face_face[j]];

            /* hypre_printf("update entry: %d\n", j_face_face[j]);  */

            last = previous[tail];
            if (last == head)
                weight_max = 0;
            else
                weight_max = i_face_weight[last];

            ierr = update_entry(weight, &weight_max,
                                previous, next, first, &last,
                                head, tail,
                                j_face_face[j]);

            last = previous[tail];
            if (last == head)
                weight_max = 0;
            else
                weight_max = i_face_weight[last];

        }

    /* find a face of the elements that have already been agglomerated
       with a maximal weight: ====================================== */

    max_weight_old = max_weight;

    face_local_max_weight = -1;
    preferred_weight = -1;

    for (l = i_AE_element[AE_counter];
            l < AE_element_counter; l++)
    {
        for (j=i_element_face[j_AE_element[l]];
                j<i_element_face[j_AE_element[l]+1]; j++)
        {
            i = j_element_face[j];

            if (max_weight_old > 1 && i_face_weight[i] > 0 &&
                    i_face_to_prefer_weight[i] > -1)
            {
                if ( max_weight < i_face_weight[i])
                {
                    face_local_max_weight = i;
                    max_weight = i_face_weight[i];
                    preferred_weight = i_face_to_prefer_weight[i];
                }

                if ( max_weight == i_face_weight[i]
                        && i_face_to_prefer_weight[i] > preferred_weight)
                {
                    face_local_max_weight = i;
                    preferred_weight = i_face_to_prefer_weight[i];
                }

            }
        }
    }

    if (face_local_max_weight > -1) goto eliminate_face;

    /* ----------------------------------------------------------------
     * eliminate and label with i_face_weight[ ] = -1
     * "boundary faces of agglomerated elements";
     * those faces will be preferred for the next coarse spaces
     * in case multiple coarse spaces are to be built;
     * ---------------------------------------------------------------*/

    for (k = i_AE_element[AE_counter]; k < AE_element_counter; k++)
    {
        for (j = i_element_face[j_AE_element[k]];
                j < i_element_face[j_AE_element[k]+1]; j++)
        {
            if (i_face_weight[j_element_face[j]] > 0)
            {
                weight = i_face_weight[j_element_face[j]];
                last = previous[tail];
                if (last == head)
                    weight_max = 0;
                else
                    weight_max = i_face_weight[last];


                ierr = remove_entry(weight, &weight_max,
                                    previous, next, first, &last,
                                    head, tail,
                                    j_element_face[j]);

                i_face_weight[j_element_face[j]] = -1;

            }
        }
    }

    if (AE_element_counter > i_AE_element[AE_counter])
    {
        /* hypre_printf("completing agglomerated element: %d\n",
          AE_counter);   */
        AE_counter++;
    }

    i_AE_element[AE_counter] = AE_element_counter;


    /* find a face with maximal weight: ---------------------------*/


    last = previous[tail];
    if (last == head) goto end_agglomerate;

    weight_max = i_face_weight[last];


    /* hypre_printf("global search: ======================================\n"); */

    face_max_weight = -1;

    k = last;
    while (k != head)
    {
        if (i_face_to_prefer_weight[k] > -1)
            face_max_weight = k;


        if (face_max_weight > -1)
        {
            max_weight = i_face_weight[face_max_weight];
            l = face_max_weight;

            while (previous[l] != head)
            {

                if (i_face_weight[previous[l]] < max_weight)
                    break;
                else if (i_face_to_prefer_weight[previous[l]] >
                         i_face_to_prefer_weight[face_max_weight])
                {
                    l = previous[l];
                    face_max_weight = l;
                }
                else
                    l = previous[l];
            }

            break;
        }


        l =previous[k];
        /* remove face k: ---------------------------------------*/


        weight = i_face_weight[k];
        last = previous[tail];
        if (last == head)
            weight_max = 0;
        else
            weight_max = i_face_weight[last];


        ierr = remove_entry(weight, &weight_max,
                            previous, next, first, &last,
                            head, tail,
                            k);


        /* i_face_weight[k] = -1; */


        k=l;
    }

    if (face_max_weight == -1) goto end_agglomerate;

    max_weight = i_face_weight[face_max_weight];

    face_local_max_weight = face_max_weight;

    goto eliminate_face;

end_agglomerate:


    /* eliminate isolated elements: ----------------------------------*/

    for (i=0; i<num_elements; i++)
    {

        if (i_element_to_AE[i] == -1)
        {
            for (j=i_element_face[i]; j < i_element_face[i+1]
                    && i_element_to_AE[i] == -1; j++)
                if (i_face_to_prefer_weight[j_element_face[j]] > -1)
                    for (k=i_face_element[j_element_face[j]];
                            k<i_face_element[j_element_face[j]+1]
                            && i_element_to_AE[i] == -1; k++)
                        if (i_element_to_AE[j_face_element[k]] != -1)
                            i_element_to_AE[i] = i_element_to_AE[j_face_element[k]];
        }

        /*
        if (i_element_to_AE[i] == -1)
        {
          i_element_face_counter = 0;
          for (j=i_element_face[i]; j < i_element_face[i+1]; j++)
            if (i_face_to_prefer_weight[j_element_face[j]] > -1)
              i_element_face_counter++;

          if (i_element_face_counter == 1)
            {
              for (j=i_element_face[i]; j < i_element_face[i+1]; j++)
        	if (i_face_to_prefer_weight[j_element_face[j]] > -1)
        	  for (k=i_face_element[j_element_face[j]];
        	       k<i_face_element[j_element_face[j]+1]; k++)
        	    if (i_element_to_AE[j_face_element[k]] != -1)
        	      i_element_to_AE[i] = i_element_to_AE[j_face_element[k]];
            }
        }
        */

        if (i_element_to_AE[i] == -1)
        {
            i_element_to_AE[i] = AE_counter;
            AE_counter++;
        }
    }

    num_AEs_pointer[0] = AE_counter;


    /* compute adjoint graph: -------------------------------------------*/

    for (i=0; i < AE_counter; i++)
        i_AE_element[i] = 0;

    for (i=0; i < num_elements; i++)
        i_AE_element[i_element_to_AE[i]]++;

    i_AE_element[AE_counter] = num_elements;

    for (i=AE_counter-1; i > -1; i--)
        i_AE_element[i] = i_AE_element[i+1] - i_AE_element[i];

    for (i=0; i < num_elements; i++)
    {
        j_AE_element[i_AE_element[i_element_to_AE[i]]] = i;
        i_AE_element[i_element_to_AE[i]]++;
    }

    for (i=AE_counter-1; i > -1; i--)
        i_AE_element[i+1] = i_AE_element[i];

    i_AE_element[0] = 0;

    /*--------------------------------------------------------------------*/
    for (i=0; i < num_faces; i++)
        if (i_face_to_prefer_weight[i] == -1) i_face_weight[i] = -1;


    hypre_TFree(i_element_to_AE);

    hypre_TFree(previous);
    hypre_TFree(next);
    hypre_TFree(first);

    return ierr;
}
Ejemplo n.º 4
0
/* just an accessor to move_entry */
int
list_move_value(linked_list_t *list, size_t srcPos, size_t dstPos)
{
    return move_entry(list, srcPos, dstPos);
}
Ejemplo n.º 5
0
static fssh_status_t
command_mv(int argc, const char* const* argv)
{
	bool force = false;

	// parse parameters
	int argi = 1;
	for (argi = 1; argi < argc; argi++) {
		const char *arg = argv[argi];
		if (arg[0] != '-')
			break;

		if (arg[1] == '\0') {
			fprintf(stderr, "Error: Invalid option \"-\"\n");
			return FSSH_B_BAD_VALUE;
		}

		for (int i = 1; arg[i]; i++) {
			switch (arg[i]) {
				case 'f':
					force = true;
					break;
				default:
					fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]);
					return FSSH_B_BAD_VALUE;
			}
		}
	}

	// check params
	int count = argc - 1 - argi;
	if (count <= 0) {
		fprintf(stderr, "Usage: %s [-f] <file>... <target>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char* target = argv[argc - 1];

	// stat the target
	struct fssh_stat st;
	fssh_status_t status = _kern_read_stat(-1, target, true, &st, sizeof(st));
	if (status != FSSH_B_OK && count != 1) {
		fprintf(stderr, "Error: Failed to stat target \"%s\": %s\n", target,
			fssh_strerror(status));
		return status;
	}

	if (status == FSSH_B_OK && FSSH_S_ISDIR(st.fssh_st_mode)) {
		// move several entries
		int targetDir = _kern_open_dir(-1, target);
		if (targetDir < 0) {
			fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n", target,
				fssh_strerror(targetDir));
			return targetDir;
		}

		// move loop
		for (; argi < argc - 1; argi++) {
			status = move_entry(-1, argv[argi], targetDir, argv[argi], force);
			if (status != FSSH_B_OK) {
				_kern_close(targetDir);
				return status;
			}
		}

		_kern_close(targetDir);
		return FSSH_B_OK;
	}

	// rename single entry
	return move_entry(-1, argv[argi], -1, target, force);
}