+ }
+
+ // sanity check (should never happen)
+ if(strlen(line) >= sizeof(line)-10)
+ {
+ _error->Error("got a overlong line from dpkg: '%s'",line);
+ line[0]=0;
+ }
+ // append to line, check if we got a complete line
+ strcat(line, buf);
+ if(buf[0] != '\n')
+ continue;
+
+ if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ std::clog << "got from dpkg '" << line << "'" << std::endl;
+
+ // pass "error" and "conffile-prompt" messages from dpkg verbatim
+ if((strncmp(line,"error",strlen("error")) == 0) ||
+ (strncmp(line,"conffile-prompt",strlen("conffile-prompt")) == 0))
+ {
+ write(OutStatusFd, line, strlen(line));
+ line[0]=0;
+ continue;
+ }
+ // line contains the dpkg status info now. it has the form:
+ // 'status: <pkg>: <pkg qstate>' (see dpkg(1) for details)
+ char* list[5];
+ TokSplitString(':', line, list, 5);
+ char *pkg = list[1];
+ char *action = list[2];
+ vector<struct DpkgState> &states = PackageOps[pkg];
+ const char *next_action = states[PackageOpsDone[pkg]].state;
+ const char *translation = states[PackageOpsDone[pkg]].str;
+ char s[200];
+ snprintf(s, sizeof(s), translation, pkg);
+ // check if the package moved to the next dpkg state
+ if(next_action && (strcmp(action, next_action) == 0))
+ {
+ // we moved from one dpkg state to a new one, report that
+ PackageOpsDone[pkg]++;
+ Done++;
+ ostringstream status;
+ // build the status str
+ status << "pmstatus:" << pkg
+ << ":" << (Done/float(Total)*100.0)
+ << ":" << s
+ << endl;
+ if(OutStatusFd > 0)
+ write(OutStatusFd, status.str().c_str(), status.str().size());
+ if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ {
+ std::clog << "send to fd: '" << status.str()
+ << "'" << std::endl;
+
+ }
+
+ }
+ if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ std::clog << "(parsed from dpkg) pkg: " << pkg
+ << " action: " << action << endl;