// File: /workspace/github_cpp_makefile_star2_O3/spjmurray[P]nagios-plugin-check-scsi-smart/check_scsi_smart.cc
// Function: check_smart_attributes(int, std::map<unsigned char, unsigned long, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, unsigned long>>>&, std::map<unsigned char, unsigned long, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, unsigned long>>>&, int&, int&, int&, int&, int&, std::ostream&)
void check_smart_attributes(int fd, SmartThresholdMap& critical_thresholds, SmartThresholdMap& warning_thresholds,
                            int& code, int& prdfail, int& advisory, int& crit, int& warn, ostream& perfdata) {

  // Load the SMART data and thresholds pages
  smart_data sd;
  ata_smart_read_data(fd, reinterpret_cast<unsigned char*>(&sd));

  smart_thresholds st;
  ata_smart_read_thresholds(fd, reinterpret_cast<unsigned char*>(&st));

  // Perform actual SMART threshold checks
  for(int i=0; i<SMART_ATTRIBUTE_NUM; i++) {

    SmartAttribute attribute(sd.attributes[i]);
    SmartThreshold threshold(st.thresholds[i]);

    if(!attribute.idValid())
      continue;

    // Check the validity of the attribute value and whether the threshold has been exceeded
    if(attribute.valueValid() && (attribute <= threshold)) {

      // Predicted failure is within 24 hours, otherwise the device lifespan has been exceeded
      if(attribute.getPreFail())
        prdfail++;
      else
        advisory++;

    }

    // Check against custom raw thresholds
    uint64_t crit_threshold = critical_thresholds[attribute.getID()];
    uint64_t warn_threshold = warning_thresholds[attribute.getID()];

    if(crit_threshold && (attribute.getRaw() >= crit_threshold)) {
      crit++;
    } else if(warn_threshold && (attribute.getRaw() >= warn_threshold)) {
      warn++;
    }

    // Accumulate the performance data
    perfdata << " " << attribute << ";";
    if(warn_threshold)
      perfdata << warn_threshold;
    perfdata << ";";
    if(crit_threshold)
      perfdata << crit_threshold;
    perfdata << ";;";

  }

  // Determine the state to report
  if(advisory || warn)
    code = max(code, NAGIOS_WARNING);

  if(prdfail || crit)
    code = max(code, NAGIOS_CRITICAL);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x448, %rsp            # imm = 0x448
movq %r9, 0x28(%rsp)
movq %r8, 0x30(%rsp)
movq %rcx, 0x20(%rsp)
movq %rdx, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movl %edi, %r14d
movq 0x490(%rsp), %rbp
xorl %r15d, %r15d
leaq 0x48(%rsp), %rsi
movq %r15, 0x3(%rsi)
movq %r15, 0x8(%rsi)
movb $-0x7b, %al
movb %al, (%rsi)
movw $0xe08, %ax             # imm = 0xE08
movw %ax, 0x1(%rsi)
movb $0x1, %al
movb %al, 0x6(%rsi)
movb $-0x50, %al
movb %al, 0xe(%rsi)
movb $-0x30, 0x4(%rsi)
movb $-0x3e, %r12b
movb %r12b, 0xc(%rsi)
movb $0x4f, %r13b
movb %r13b, 0xa(%rsi)
leaq 0x248(%rsp), %rcx
movl $0x10, %edx
movl $0x200, %r8d            # imm = 0x200
callq 0x48aa
leaq 0x10(%rsp), %rbx
movq %r15, 0x3(%rbx)
movq %r15, 0x8(%rbx)
movb $-0x7b, %al
movb %al, (%rbx)
movw $0xe08, %ax             # imm = 0xE08
movw %ax, 0x1(%rbx)
movb $0x1, %al
movb %al, 0x6(%rbx)
movb $-0x50, %al
movb %al, 0xe(%rbx)
movb $-0x2f, 0x4(%rbx)
movb %r12b, 0xc(%rbx)
movb %r13b, 0xa(%rbx)
leaq 0x48(%rsp), %rcx
movl %r14d, %edi
movq %rbx, %rsi
movl $0x10, %edx
movl $0x200, %r8d            # imm = 0x200
callq 0x48aa
movl $0x2, %r12d
leaq 0xf(%rsp), %r14
leaq (%rsp,%r12), %rsi
addq $0x248, %rsi            # imm = 0x248
movq %rbx, %rdi
callq 0x5e4c
leaq (%rsp,%r12), %rsi
addq $0x48, %rsi
movq %r14, %rdi
callq 0x5f74
cmpb $0x0, 0x10(%rsp)
je 0x4ca7
movb 0x13(%rsp), %al
decb %al
cmpb $-0x4, %al
ja 0x4bce
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5ed4
testb %al, %al
je 0x4bce
cmpb $0x0, 0x11(%rsp)
movq 0x28(%rsp), %rax
cmovneq 0x30(%rsp), %rax
incl (%rax)
movb 0x10(%rsp), %al
movb %al, 0xe(%rsp)
movq 0x38(%rsp), %rdi
leaq 0xe(%rsp), %r15
movq %r15, %rsi
callq 0x5772
movq (%rax), %r13
movb 0x10(%rsp), %al
movb %al, 0xe(%rsp)
movq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x5772
movq (%rax), %r15
movq 0x18(%rsp), %rax
leaq -0x1(%r13), %rdx
movq 0x480(%rsp), %rcx
cmpq %rax, %rdx
jb 0x4c2a
leaq -0x1(%r15), %rdx
movq 0x488(%rsp), %rcx
cmpq %rax, %rdx
jae 0x4c2c
incl (%rcx)
movl $0x1, %edx
movq %rbp, %rdi
leaq 0x1613(%rip), %rsi      # 0x624e
callq 0x41c0
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x5edd
movl $0x1, %edx
movq %rax, %rdi
leaq 0x15a9(%rip), %rsi      # 0x6203
callq 0x41c0
testq %r15, %r15
je 0x4c6f
movq %rbp, %rdi
movq %r15, %rsi
callq 0x40d0
movl $0x1, %edx
movq %rbp, %rdi
leaq 0x1585(%rip), %rsi      # 0x6203
callq 0x41c0
testq %r13, %r13
je 0x4c93
movq %rbp, %rdi
movq %r13, %rsi
callq 0x40d0
movl $0x2, %edx
movq %rbp, %rdi
leaq 0x1560(%rip), %rsi      # 0x6202
callq 0x41c0
addq $0xc, %r12
cmpq $0x16a, %r12            # imm = 0x16A
jne 0x4b75
movq 0x488(%rsp), %rax
movl (%rax), %eax
movq 0x28(%rsp), %rcx
orl (%rcx), %eax
je 0x4cdf
movq 0x20(%rsp), %rdx
movl (%rdx), %eax
cmpl $0x2, %eax
movl $0x1, %ecx
cmovgel %eax, %ecx
movl %ecx, (%rdx)
movq 0x480(%rsp), %rax
movl (%rax), %eax
movq 0x30(%rsp), %rcx
orl (%rcx), %eax
je 0x4d06
movq 0x20(%rsp), %rdx
movl (%rdx), %eax
cmpl $0x3, %eax
movl $0x2, %ecx
cmovgel %eax, %ecx
movl %ecx, (%rdx)
addq $0x448, %rsp            # imm = 0x448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq