예제 #1
0
파일: int.c 프로젝트: openSUSE/hwinfo
/*
 * Tag ide soft raid disks.
 */
void int_softraid(hd_data_t *hd_data)
{
  hd_t *hd;
  str_list_t *raid, *sl, *raid_sysfs = NULL, *sl1;
  size_t len;
  char *s;

  if(hd_data->flags.fast) return;

  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(
      hd->base_class.id == bc_storage_device &&
      hd->status.available != status_no
    ) break;
  }

  /* no disks -> no check necessary */
  if(!hd) return;
  
  raid = read_file("| /sbin/dmraid -rc 2>/dev/null", 0, 0);

  for(sl = raid; sl; sl = sl->next) {
    s = *sl->str ? strchr(sl->str + 1, '/') : NULL;
    if(s) {
      sl1 = add_str_list(&raid_sysfs, NULL);
      str_printf(&sl1->str, 0, "/block%s", s);
      len = strlen(sl1->str);
      if(len) sl1->str[len - 1] = 0;
    }
  }

  free_str_list(raid);

  ADD2LOG("----- soft raid devices -----\n");
  for(sl = raid_sysfs; sl; sl = sl->next) {
    ADD2LOG("  %s\n", sl->str);
  }
  ADD2LOG("----- soft raid devices end -----\n");

  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(search_str_list(raid_sysfs, hd->sysfs_id)) {
      hd->is.softraiddisk = 1;
    }
  }

  free_str_list(raid_sysfs);

}
예제 #2
0
static void free_args(struct isl_arg *arg, void *opt)
{
	int i;

	for (i = 0; arg[i].type != isl_arg_end; ++i) {
		switch (arg[i].type) {
		case isl_arg_child:
			free_child(&arg[i], opt);
			break;
		case isl_arg_arg:
		case isl_arg_str:
			free(*(char **)(((char *)opt) + arg[i].offset));
			break;
		case isl_arg_str_list:
			free_str_list(&arg[i], opt);
			break;
		case isl_arg_user:
			free_user(&arg[i], opt);
			break;
		case isl_arg_alias:
		case isl_arg_bool:
		case isl_arg_choice:
		case isl_arg_flags:
		case isl_arg_int:
		case isl_arg_long:
		case isl_arg_ulong:
		case isl_arg_version:
		case isl_arg_footer:
		case isl_arg_end:
			break;
		}
	}
}
예제 #3
0
파일: int.c 프로젝트: openSUSE/hwinfo
void int_update_driver_data(hd_data_t *hd_data, hd_t *hd)
{
  hd_sysfsdrv_t *sf;
  str_list_t *sl;

  hd->driver_modules = free_str_list(hd->driver_modules);

  for(sl = hd->drivers; sl; sl = sl->next) {
    for(sf = hd_data->sysfsdrv; sf; sf = sf->next) {
      if(sf->module && !strcmp(sf->driver, sl->str)) {
        add_str_list(&hd->driver_modules, sf->module);
      }
    }
  }

  hd->driver = free_mem(hd->driver);
  hd->driver_module = free_mem(hd->driver_module);

  if(hd->drivers && hd->drivers->str) {
    hd->driver = new_str(hd->drivers->str);

    for(sf = hd_data->sysfsdrv; sf; sf = sf->next) {
      if(sf->module && !strcmp(sf->driver, hd->driver)) {
        hd->driver_module = new_str(sf->module);
      }
    }
  }
}
예제 #4
0
void hd_scan_sysfs_usb(hd_data_t *hd_data)
{
  if(!hd_probe_feature(hd_data, pr_usb)) return;

  hd_data->module = mod_usb;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->proc_usb = free_str_list(hd_data->proc_usb);
  hd_data->usb = NULL;

  PROGRESS(1, 0, "sysfs drivers");
  
  hd_sysfs_driver_list(hd_data);

  PROGRESS(2, 0, "usb");

  get_usb_devs(hd_data);

  PROGRESS(3, 1, "joydev mod");
  load_module(hd_data, "joydev");
    
  PROGRESS(3, 2, "evdev mod");
  load_module(hd_data, "evdev");

  PROGRESS(3, 3, "input");
  get_input_devs(hd_data);

  PROGRESS(3, 4, "lp");
  get_printer_devs(hd_data);

  PROGRESS(3, 5, "serial");
  get_serial_devs(hd_data);

}
예제 #5
0
int main(int argc,char **argv)
{
  int n;
  int from_ix;
  int ix;
  struct str_list list;
  struct str_list_elem *work_elem;

  if (argc < 4) {
    printf("usage: test_str_list find_str from_ix str (str ...)\n");
    return 1;
  }

  sscanf(argv[2],"%d",&from_ix);

  list.num_elems = 0;

  for (n = 3; n < argc; n++) {
    add_str_list_elem(&list,argv[n],true);
  }

  printf("%d\n",member_of_str_list_from_ix(&list,from_ix,argv[1],&ix));

  free_str_list(&list);

  return 0;
}
예제 #6
0
static void info_bar_response_cb(GtkInfoBar *info_bar, gint response_id, gpointer user_data)
{
	GSList *library_dir = NULL;

	struct con_win *cwin = user_data;
	const gchar *dir = g_get_user_special_dir(G_USER_DIRECTORY_MUSIC);

	gtk_widget_destroy(GTK_WIDGET(info_bar));

	switch (response_id)
	{
		case GTK_RESPONSE_CANCEL:
			break;
		case GTK_RESPONSE_YES:
			library_dir = g_slist_append(library_dir, g_strdup(dir));
			pragha_preferences_set_filename_list(cwin->preferences,
				                             GROUP_LIBRARY,
				                             KEY_LIBRARY_DIR,
				                             library_dir);
			free_str_list(library_dir);

			pragha_scanner_scan_library(cwin->scanner);
			break;
		default:
			g_warn_if_reached();
	}
}
예제 #7
0
파일: block.c 프로젝트: doughdemon/hwinfo
void hd_scan_sysfs_block(hd_data_t *hd_data)
{
  if(!hd_probe_feature(hd_data, pr_block)) return;

  hd_data->module = mod_block;

  /* some clean-up */
  remove_hd_entries(hd_data);

  hd_data->disks = free_str_list(hd_data->disks);
  hd_data->partitions = free_str_list(hd_data->partitions);
  hd_data->cdroms = free_str_list(hd_data->cdroms);

  if(hd_probe_feature(hd_data, pr_block_mods)) {
    PROGRESS(1, 0, "block modules");
    // load_module(hd_data, "ide-cd");
    load_module(hd_data, "ide-cd_mod");
    load_module(hd_data, "ide-disk");
    load_module(hd_data, "sr_mod");
    load_module(hd_data, "sd_mod");
#if !defined(__s390__) && !defined(__s390x__)
    load_module(hd_data, "st");
#endif
  }

  PROGRESS(2, 0, "sysfs drivers");

  hd_sysfs_driver_list(hd_data);

  PROGRESS(3, 0, "cdrom");

  read_cdroms(hd_data);

  PROGRESS(4, 0, "partition");

  read_partitions(hd_data);

  PROGRESS(5, 0, "get sysfs block dev data");

  get_block_devs(hd_data);

  if(hd_data->cdrom) {
    ADD2LOG("oops: cdrom list not empty\n");
  }
}
예제 #8
0
void
pragha_scanner_free(PraghaScanner *scanner)
{
	if(scanner->update_timeout) {
		g_cancellable_cancel (scanner->cancellable);
		g_thread_join (scanner->no_files_thread);
		g_thread_join (scanner->worker_thread);
	}

	g_hash_table_destroy(scanner->tracks_table);
	free_str_list(scanner->folder_list);
	free_str_list(scanner->folder_scanned);
	g_mutex_clear (&scanner->no_files_mutex);
	g_mutex_clear (&scanner->files_scanned_mutex);
	g_object_unref(scanner->cancellable);

	g_slice_free (PraghaScanner, scanner);
}
예제 #9
0
void at_cmd(hd_data_t *hd_data, char *at, int raw, int log_it)
{
  static unsigned u = 1;
  char *s, *s0;
  ser_device_t *sm;
  str_list_t *sl;
  int modems = 0;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      sm->buf_len = 0;
      modems++;
    }
  }

  if(modems == 0) return;

  PROGRESS(9, u, "write at cmd");
  write_modem(hd_data, at);
  PROGRESS(9, u, "read at resp");
  usleep (200000);
  read_modem(hd_data);
  PROGRESS(9, u, "read ok");
  u++;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      sm->at_resp = free_str_list(sm->at_resp);
      if(sm->buf_len == 0 || raw) continue;
      s0 = sm->buf;
      while((s = strsep(&s0, "\r\n"))) {
        if(*s) add_str_list(&sm->at_resp, s);
      }
    }
  }

  if(!(hd_data->debug & HD_DEB_MODEM) || !log_it) return;

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->do_io) {
      ADD2LOG("%s@%u: %s\n", sm->dev_name, sm->cur_baud, at);
      if(raw) {
        ADD2LOG("  ");
        hexdump(&hd_data->log, 1, sm->buf_len, sm->buf);
        ADD2LOG("\n");
      }
      else {
        for(sl = sm->at_resp; sl; sl = sl->next) ADD2LOG("  %s\n", sl->str);
      }
    }
  }
}
예제 #10
0
void hd_scan_modem(hd_data_t *hd_data)
{
  ser_device_t *sm, *sm_next;

  if(!hd_probe_feature(hd_data, pr_modem)) return;

  hd_data->module = mod_modem;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->ser_modem = NULL;

  PROGRESS(1, 0, "serial");

  hd_fork(hd_data, 15, 120);

  if(hd_data->flags.forked) {
    get_serial_modem(hd_data);
    hd_move_to_shm(hd_data);
    if((hd_data->debug & HD_DEB_MODEM)) dump_ser_modem_data(hd_data);
  }
  else {
    /* take data from shm */
    hd_data->ser_modem = ((hd_data_t *) (hd_data->shm.data))->ser_modem;
    if((hd_data->debug & HD_DEB_MODEM)) dump_ser_modem_data(hd_data);
  }

  hd_fork_done(hd_data);

  add_serial_modem(hd_data);

  hd_shm_clean(hd_data);

  for(sm = hd_data->ser_modem; sm; sm = sm_next) {
    sm_next = sm->next;

    free_str_list(sm->at_resp);

    free_mem(sm->dev_name);
    free_mem(sm->serial);
    free_mem(sm->class_name);
    free_mem(sm->dev_id);
    free_mem(sm->user_name);
    free_mem(sm->vend);
    free_mem(sm->init_string1);
    free_mem(sm->init_string2);

    free_mem(sm);
  }
  hd_data->ser_modem = NULL;

}
예제 #11
0
struct str_elem *html_to_dict(Hashtable dst, Hashtable dict,
        const char *contents, int index, struct str_elem *str_list)
{
    char *text = malloc(65535);
    bzero(text, 65535);
    html_gettext(contents, text);

    struct str_elem *segs = SIMPLE_MMSEG(dict, (unsigned char *)text);
    struct str_elem *seg = segs;
    struct str_elem *str_tmp = str_list, *str_new;
    struct int_elem *html_index_ent = NULL, *html_index_ent_tmp = NULL;
    struct int_elem **pte = NULL;

    do {
        if (!seg->str)
            continue;

        html_index_ent_tmp = malloc(sizeof(*html_index_ent_tmp));
        html_index_ent_tmp->value = index;
        html_index_ent_tmp->next = NULL;
        if ((html_index_ent = (IntElem)HTSearch(dst, seg->str))) {
            pte = &html_index_ent;
            if (!(*pte)->next) {
                if (html_index_ent->value == index)
                    /* this index exists */
                    free(html_index_ent_tmp);
                else
                    html_index_ent->next = html_index_ent_tmp;
            } else {
                /* seek to the last two */
                while (pte = &(*pte)->next, (*pte)->next);
                if ((*pte)->value == index)
                    /* this index exists */
                    free(html_index_ent_tmp);
                else
                    (*pte)->next = html_index_ent_tmp;
            }
        } else {
            /* save the string to str list */
            str_new = malloc(sizeof(*str_new));
            str_new->str = strdup(seg->str);
            str_new->next = str_tmp;
            str_tmp = str_new;
            HTInsert(dst, seg->str, html_index_ent_tmp);
        }
    } while ((seg = seg->next));
    free_str_list(segs);
    return str_tmp;
}
예제 #12
0
파일: manual.c 프로젝트: jakeogh/hwinfo
/*
 * read an entry
 */
hal_prop_t *hd_manual_read_entry_old(const char *id)
{
  char path[PATH_MAX];
  int line;
  str_list_t *sl, *sl0;
  char *s, *s1, *s2;
  hal_prop_t *prop_list = NULL, *prop = NULL;

  if(!id) return NULL;

  snprintf(path, sizeof path, "%s/%s", hd_get_hddb_path("unique-keys"), id);

  if(!(sl0 = read_file(path, 0, 0))) return prop_list;

  for(line = 1, sl = sl0; sl; sl = sl->next, line++) {
    s = sl->str;
    while(isspace(*s)) s++;
    if(!*s || *s == '#' || *s == ';') continue;	/* empty lines & comments */

    s2 = s;
    s1 = strsep(&s2, "=");

    if(!s2 && *s == '[') continue;

    if(!s2) break;

    if(s1) {
      if(prop) {
        prop->next = new_mem(sizeof *prop);
        prop = prop->next;
      }
      else {
        prop_list = prop = new_mem(sizeof *prop);
      }

      prop->type = p_string;
      for(s = s1; *s; s++) if(*s >= 'A' && *s <= 'Z') *s += 'a' - 'A';
      str_printf(&prop->key, 0, "hwinfo.%s", s1);
      prop->val.str = canon_str(s2, strlen(s2));
    }
  }

  free_str_list(sl0);

  return prop_list;
}
예제 #13
0
파일: klog.c 프로젝트: jakeogh/hwinfo
/*
 * Read kernel log info. Combine with /var/log/boot.msg.
 * Remove time stamps.
 */
void read_klog(hd_data_t *hd_data)
{
  str_list_t *sl, **sl_new;
  char *str, *s;

  _read_klog(hd_data);

  free_str_list(hd_data->klog_raw);
  hd_data->klog_raw = hd_data->klog;
  hd_data->klog = NULL;

  for(sl = hd_data->klog_raw, sl_new = &hd_data->klog; sl; sl = sl->next, sl_new = &(*sl_new)->next) {
    str = add_str_list(sl_new, sl->str)->str;
    if(str[0] == '<' && str[1] && str[2] == '>' && str[3] == '[') {
      s = str + 4;
      while(*s && *s != ']') s++;
      if(*s) s++;
      if(*s) s++;	// skip space
      for(str += 3; (*str++ = *s++););
    }
  }
}
예제 #14
0
static void copy_str_list(const m_option_t* opt,void* dst, void* src) {
  int n;
  char **d,**s;

  if(!(dst && src)) return;
  s = VAL(src);

  if(VAL(dst))
    free_str_list(dst);

  if(!s) {
    VAL(dst) = NULL;
    return;
  }

  for(n = 0 ; s[n] != NULL ; n++)
    /* NOTHING */;
  d = malloc((n+1)*sizeof(char*));
  for( ; n >= 0 ; n--)
    d[n] = s[n] ? strdup(s[n]) : NULL;

  VAL(dst) = d;
}
예제 #15
0
static int parse_str_list(const m_option_t* opt,const char *name, char *param, void* dst, int src) {
  int n = 0,len = strlen(opt->name);
  char *str;
  char *ptr = param, *last_ptr, **res;
  int op = OP_NONE;

  if(opt->name[len-1] == '*' && ((int)strlen(name) > len - 1)) {
    const char* n = &name[len-1];
    if(strcasecmp(n,"-add") == 0)
      op = OP_ADD;
    else if(strcasecmp(n,"-pre") == 0)
      op = OP_PRE;
    else if(strcasecmp(n,"-del") == 0)
      op = OP_DEL;
    else if(strcasecmp(n,"-clr") == 0)
      op = OP_CLR;
    else
      return M_OPT_UNKNOWN;
  }

  // Clear the list ??
  if(op == OP_CLR) {
    if(dst)
      free_str_list(dst);
    return 0;
  }

  // All other ops need a param
  if (param == NULL || strlen(param) == 0)
      return M_OPT_MISSING_PARAM;


  while(ptr[0] != '\0') {
    ptr = get_nextsep(ptr, LIST_SEPARATOR, 0);
    if(!ptr) {
      n++;
      break;
    }
    ptr++;
    n++;
  }
  if(n == 0)
    return M_OPT_INVALID;
  if( ((opt->flags & M_OPT_MIN) && (n < opt->min)) ||
      ((opt->flags & M_OPT_MAX) && (n > opt->max)) )
    return M_OPT_OUT_OF_RANGE;

  if(!dst) return 1;

  res = malloc((n+2)*sizeof(char*));
  ptr = str = strdup(param);
  n = 0;

  while(1) {
    last_ptr = ptr;
    ptr = get_nextsep(ptr, LIST_SEPARATOR, 1);
    if(!ptr) {
      res[n] = strdup(last_ptr);
      n++;
      break;
    }
    len = ptr - last_ptr;
    res[n] = malloc(len + 1);
    if(len) strncpy(res[n],last_ptr,len);
    res[n][len] = '\0';
    ptr++;
    n++;
  }
  res[n] = NULL;
  free(str);

  switch(op) {
  case OP_ADD:
    return str_list_add(res,n,dst,0);
  case OP_PRE:
    return str_list_add(res,n,dst,1);
  case OP_DEL:
    return str_list_del(res,n,dst);
  }

  if(VAL(dst))
    free_str_list(dst);
  VAL(dst) = res;

  return 1;
}
예제 #16
0
/*
 * * m_list *      parv[0] = sender prefix *      parv[1] = channel
 */
DLLFUNC CMD_FUNC(m_list)
{
	aChannel *chptr;
	TS   currenttime = TStime();
	char *name, *p = NULL;
	LOpts *lopt = NULL;
	Link *lp;
	int  usermax, usermin, error = 0, doall = 0;
	TS   chantimemin, chantimemax;
	TS   topictimemin, topictimemax;
	Link *yeslist = NULL, *nolist = NULL;

	static char *usage[] = {
		"   Usage: /LIST <options>",
		"",
		"If you don't include any options, the default is to send you the",
		"entire unfiltered list of channels. Below are the options you can",
		"use, and what channels LIST will return when you use them.",
		">number  List channels with more than <number> people.",
		"<number  List channels with less than <number> people.",
		"C>number List channels created between now and <number> minutes ago.",
		"C<number List channels created earlier than <number> minutes ago.",
		"T>number List channels whose topics are older than <number> minutes",
		"         (Ie, they have not changed in the last <number> minutes.",
		"T<number List channels whose topics are not older than <number> minutes.",
		"*mask*   List channels that match *mask*",
		"!*mask*  List channels that do not match *mask*",
		NULL
	};

	/* Some starting san checks -- No interserver lists allowed. */
	if (cptr != sptr || !sptr->user)
		return 0;

	/* If a /list is in progress, then another one will cancel it */
	if ((lopt = sptr->user->lopt) != NULL)
	{
		sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);
		free_str_list(sptr->user->lopt->yeslist);
		free_str_list(sptr->user->lopt->nolist);
		MyFree(sptr->user->lopt);
		sptr->user->lopt = NULL;
		return 0;
	}

	if (parc < 2 || BadPtr(parv[1]))
	{

		sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, parv[0]);
		lopt = sptr->user->lopt = (LOpts *) MyMalloc(sizeof(LOpts));
		memset(lopt, '\0', sizeof(LOpts));

		lopt->showall = 1;

		if (DBufLength(&cptr->sendQ) < 2048)
			send_list(cptr, 64);

		return 0;
	}

	if ((parc == 2) && (parv[1][0] == '?') && (parv[1][1] == '\0'))
	{
		char **ptr = usage;
		for (; *ptr; ptr++)
			sendto_one(sptr, rpl_str(RPL_LISTSYNTAX),
			    me.name, cptr->name, *ptr);
		return 0;
	}

	sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, parv[0]);

	chantimemax = topictimemax = currenttime + 86400;
	chantimemin = topictimemin = 0;
	usermin = 1;		/* Minimum of 1 */
	usermax = -1;		/* No maximum */

	for (name = strtok_r(parv[1], ",", &p); name && !error;
	    name = strtok_r(NULL, ",", &p))
	{

		switch (*name)
		{
		  case '<':
			  usermax = atoi(name + 1) - 1;
			  doall = 1;
			  break;
		  case '>':
			  usermin = atoi(name + 1) + 1;
			  doall = 1;
			  break;
		  case 'C':
		  case 'c':	/* Channel TS time -- creation time? */
			  ++name;
			  switch (*name++)
			  {
			    case '<':
				    chantimemax = currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    case '>':
				    chantimemin = currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    default:
				    sendto_one(sptr, err_str(ERR_LISTSYNTAX), me.name, cptr->name);
				    error = 1;
			  }
			  break;
#ifdef LIST_USE_T
		  case 'T':
		  case 't':
			  ++name;
			  switch (*name++)
			  {
			    case '<':
				    topictimemax =
					currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    case '>':
				    topictimemin =
					currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    default:
				    sendto_one(sptr,
					err_str(ERR_LISTSYNTAX),
					me.name, cptr->name,
					"Bad list syntax, type /list ?");
				    error = 1;
			  }
			  break;
#endif
		  default:	/* A channel, possibly with wildcards.
				 * Thought for the future: Consider turning wildcard
				 * processing on the fly.
				 * new syntax: !channelmask will tell ircd to ignore
				 * any channels matching that mask, and then
				 * channelmask will tell ircd to send us a list of
				 * channels only masking channelmask. Note: Specifying
				 * a channel without wildcards will return that
				 * channel even if any of the !channelmask masks
				 * matches it.
				 */
			  if (*name == '!')
			  {
				  doall = 1;
				  lp = make_link();
				  lp->next = nolist;
				  nolist = lp;
				  DupString(lp->value.cp, name + 1);
			  }
			  else if (strchr(name, '*') || strchr(name, '?'))
			  {
				  doall = 1;
				  lp = make_link();
				  lp->next = yeslist;
				  yeslist = lp;
				  DupString(lp->value.cp, name);
			  }
			  else	/* Just a normal channel */
			  {
				  chptr = find_channel(name, NullChn);
				  if (chptr && (ShowChannel(sptr, chptr) || OPCanSeeSecret(sptr))) {
#ifdef LIST_SHOW_MODES
					modebuf[0] = '[';
					channel_modes(sptr, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), chptr);
					if (modebuf[2] == '\0')
						modebuf[0] = '\0';
					else
						strlcat(modebuf, "]", sizeof modebuf);
#endif
					  sendto_one(sptr,
					      rpl_str(RPL_LIST),
					      me.name, parv[0],
					      name, chptr->users,
#ifdef LIST_SHOW_MODES
					      modebuf,
#endif
					      (chptr->topic ? chptr->topic :
					      ""));
}
			  }
		}		/* switch */
	}			/* while */

	if (doall)
	{
		lopt = sptr->user->lopt = (LOpts *) MyMalloc(sizeof(LOpts));
		memset(lopt, '\0', sizeof(LOpts));
		lopt->usermin = usermin;
		lopt->usermax = usermax;
		lopt->topictimemax = topictimemax;
		lopt->topictimemin = topictimemin;
		lopt->chantimemax = chantimemax;
		lopt->chantimemin = chantimemin;
		lopt->nolist = nolist;
		lopt->yeslist = yeslist;

		if (DBufLength(&cptr->sendQ) < 2048)
			send_list(cptr, 64);
		return 0;
	}

	sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);

	return 0;
}
예제 #17
0
파일: klog.c 프로젝트: jakeogh/hwinfo
/*
 * Read kernel log info. Combine with /var/log/boot.msg.
 */
void _read_klog(hd_data_t *hd_data)
{
  char buf[0x2000 + 1], *s;
  int i, j, len, n;
  str_list_t *sl, *sl1, *sl2, *sl_last, **ssl, *sl_next;

  /* some clean-up */
  hd_data->klog = free_str_list(hd_data->klog);

  sl1 = read_file(KLOG_BOOT, 0, 0);
  sl2 = NULL;

  /*
   * remove non-canonical lines (not starting with <[0-9]>) at the start and
   * at the end
   */

  /* note: the implementations assumes that at least *one* line is ok */
  for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
    if(str_ok(sl)) {
      if(sl_last) {
        sl_last->next = NULL;
        free_str_list(sl1);
        sl1 = sl;
      }
      break;
    }
  }

  for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
    if(!str_ok(sl)) {
      if(sl_last) {
        sl_last->next = NULL;
        free_str_list(sl);
      }
      break;
    }
  }

  n = klogctl(3, buf, sizeof buf - 1);
  if(n <= 0) {
    hd_data->klog = sl1;
    return;
  }

  if(n > (int) sizeof buf - 1) n = sizeof buf - 1;
  buf[n] = 0;
  for(i = j = 0; i < n; i++) {
    if(buf[i] == '\n') {
      len = i - j + 1;
      s = new_mem(len + 1);
      memcpy(s, buf + j, len);
      add_str_list(&sl2, s);
      s = free_mem(s);
      j = i + 1;
    }
  }

  /* the 1st line may be incomplete */
  if(sl2 && !str_ok(sl2)) {
    sl_next = sl2->next;
    sl2->next = NULL;
    free_str_list(sl2);
    sl2 = sl_next;
  }

  if(!sl1) {
    hd_data->klog = sl2;
    return;
  }

  if(sl1 && !sl2) {
    hd_data->klog = sl1;
    return;
  }

  /* now, try to join sl1 & sl2 */
  for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
    if(!str_list_cmp(sl, sl2)) {
      free_str_list(sl);
      if(sl_last)
        sl_last->next = NULL;
      else
        sl1 = NULL;
      break;
    }
  }

  /* append sl2 to sl1 */
  for(ssl = &sl1; *ssl; ssl = &(*ssl)->next);
  *ssl = sl2;

  hd_data->klog = sl1;
}
예제 #18
0
void hd_scan_floppy(hd_data_t *hd_data)
{
  hd_t *hd;
  char b0[10], b1[10], c;
  unsigned u;
  int fd, i, floppy_ctrls = 0, floppy_ctrl_idx = 0;
  str_list_t *sl;
  hd_res_t *res;
  int floppy_stat[2] = { 1, 1 };
  unsigned floppy_created = 0;

  if(!hd_probe_feature(hd_data, pr_floppy)) return;

  hd_data->module = mod_floppy;

   /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->floppy = free_str_list(hd_data->floppy);

  PROGRESS(1, 0, "get nvram");

  /*
   * Look for existing floppy controller entries (typically there will be
   * *none*).
   */
  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(hd->base_class.id == bc_storage && hd->sub_class.id == sc_sto_floppy) {
      floppy_ctrls++;
      floppy_ctrl_idx = hd->idx;
    }
  }

  /*
   * Is enough to load the nvram module.
   *
   * Note: although you must be root to access /dev/nvram, every
   * user can read /proc/nvram.
   */
  fd = open(DEV_NVRAM, O_RDONLY | O_NONBLOCK);
  if(fd >= 0) close(fd);

  if(
    !(hd_data->floppy = read_file(PROC_NVRAM_24, 0, 0)) &&
    !(hd_data->floppy = read_file(PROC_NVRAM_22, 0, 0))
  );

  if(hd_data->floppy && (hd_data->debug & HD_DEB_FLOPPY)) dump_floppy_data(hd_data);

  if(!hd_data->klog) read_klog(hd_data);

  for(sl = hd_data->klog; sl; sl = sl->next) {
    if(sscanf(sl->str, "<4>floppy%u: no floppy controllers foun%c", &u, &c) == 2) {
      if(u < sizeof floppy_stat / sizeof *floppy_stat) {
        floppy_stat[u] = 0;
      }
    }
  }

  if(hd_data->floppy) {
    PROGRESS(2, 0, "nvram info");
    sl = hd_data->floppy;
  }
  else {
    PROGRESS(2, 0, "klog info");
    sl = hd_data->klog;
  }

  for(; sl; sl = sl->next) {
    if(hd_data->floppy) {
      i = sscanf(sl->str, " Floppy %u type : %8[0-9.]'' %8[0-9.]%c", &u, b0, b1, &c) == 4;
    }
    else {
      i = sscanf(sl->str, "<6>Floppy drive(s): fd%u is %8[0-9.]%c", &u, b1, &c) == 3;
      *b0 = 0;
    }

    if(i) {
      if(
        !floppy_ctrls &&
        u < sizeof floppy_stat / sizeof *floppy_stat &&
        floppy_stat[u]
      ) {
        /* create one, if missing (there's no floppy without a controller...) */
        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_storage;
        hd->sub_class.id = sc_sto_floppy;
        floppy_ctrl_idx = hd->idx;
        floppy_ctrls++;
      }

      if(floppy_ctrls && !(floppy_created & (1 << u))) {
        hd = add_hd_entry(hd_data, __LINE__, 0);
        hd->base_class.id = bc_storage_device;
        hd->sub_class.id = sc_sdev_floppy;
        hd->bus.id = bus_floppy;
        hd->slot = u;
        str_printf(&hd->unix_dev_name, 0, "/dev/fd%u", u);

        floppy_created |= 1 << u;

        if(*b0) {
          res = add_res_entry(&hd->res, new_mem(sizeof *res));
          res->size.type = res_size;
          res->size.val1 = str2float(b0, 2);
          res->size.unit = size_unit_cinch;
        }

        /* 'k' or 'M' */
        i = c == 'M' ? str2float(b1, 3) : str2float(b1, 0);

        res = add_res_entry(&hd->res, new_mem(sizeof *res));
        res->size.type = res_size;
        res->size.val1 = i << 1;
        res->size.val2 = 0x200;
        res->size.unit = size_unit_sectors;

        /* the only choice... */
        if(floppy_ctrls == 1) hd->attached_to = floppy_ctrl_idx;
      }
    }
  }
}
예제 #19
0
/* Now just empty ignore-list, in future reload dynamic help.
 * Move out to help.c -Donwulff */
void reset_help(void)
{
	free_str_list(helpign);
}
예제 #20
0
static gboolean
pragha_scanner_worker_finished (gpointer data)
{
	GtkWidget *msg_dialog;
	gchar *last_scan_time = NULL;
	PraghaPreferences *preferences;
	PraghaDatabase *database;
	GSList *list;

	PraghaScanner *scanner = data;

	/* Stop updates */

	g_source_remove(scanner->update_timeout);

	/* Ensure that the other thread has finished */
	g_thread_join (scanner->no_files_thread);

	/* If not cancelled, update database and show a dialog */
	if(!g_cancellable_is_cancelled (scanner->cancellable)) {
		/* Hide the scanner and show the dialog */

		gtk_widget_hide(scanner->hbox);
		msg_dialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(scanner->hbox))),
		                                    GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
		                                    GTK_MESSAGE_INFO,
		                                    GTK_BUTTONS_OK,
		                                    "%s",
		                                    _("Library scan complete"));

		g_signal_connect(G_OBJECT(msg_dialog), "response",
		                 G_CALLBACK(pragha_scanner_finished_dialog_response_cb),
		                 scanner);

		g_signal_connect(G_OBJECT(msg_dialog), "delete-event",
		                 G_CALLBACK(pragha_scanner_finished_dialog_delete),
		                 scanner);

		gtk_widget_show_all(msg_dialog);

		/* Save new database and update the library view */

		set_watch_cursor(msg_dialog);
		set_watch_cursor(scanner->hbox);

		database = pragha_database_get();

		pragha_database_begin_transaction (database);

		pragha_database_flush (database);
		g_hash_table_foreach (scanner->tracks_table,
		                      pragha_scanner_add_track_db,
		                      database);


		/* Import playlist detected. */

		for (list = scanner->playlists ; list != NULL; list = list->next)
			pragha_scanner_import_playlist(database, list->data);

		pragha_database_commit_transaction (database);

		pragha_database_change_tracks_done (database);
		g_object_unref(database);

		remove_watch_cursor(scanner->hbox);
		remove_watch_cursor(msg_dialog);

		/* Save finished time and folders scanned. */

		g_get_current_time(&scanner->last_update);
		last_scan_time = g_time_val_to_iso8601(&scanner->last_update);
		preferences = pragha_preferences_get();
		pragha_preferences_set_string(preferences,
			                     GROUP_LIBRARY,
			                     KEY_LIBRARY_LAST_SCANNED,
			                     last_scan_time);
		g_free(last_scan_time);

		pragha_preferences_set_filename_list(preferences,
			                             GROUP_LIBRARY,
			                             KEY_LIBRARY_SCANNED,
			                             scanner->folder_list);
		g_object_unref(G_OBJECT(preferences));
	}
	else {
		gtk_widget_hide(scanner->hbox);
	}

	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(scanner->progress_bar), NULL);
	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(scanner->progress_bar), 0.0);

	/* Clean memory */

	g_hash_table_remove_all(scanner->tracks_table);
	free_str_list(scanner->folder_list);
	scanner->folder_list = NULL;
	free_str_list(scanner->folder_scanned);
	scanner->folder_scanned = NULL;

	free_str_list(scanner->playlists);
	scanner->playlists = NULL;

	scanner->no_files = 0;
	scanner->files_scanned = 0;

	g_cancellable_reset (scanner->cancellable);
	scanner->update_timeout = 0;

	return FALSE;
}
예제 #21
0
void get_serial_modem(hd_data_t *hd_data)
{
  hd_t *hd;
  int i, j, fd;
  unsigned modem_info, baud;
  char *command;
  ser_device_t *sm;
  int chk_usb = hd_probe_feature(hd_data, pr_modem_usb);

  /* serial modems & usb modems */
  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(
      (
        (
          hd->base_class.id == bc_comm &&
          hd->sub_class.id == sc_com_ser &&
          !hd->tag.ser_skip &&
          hd->tag.ser_device != 2 &&		/* cf. serial.c */
          !has_something_attached(hd_data, hd)
        ) ||
        (
          chk_usb &&
          hd->bus.id == bus_usb &&
          hd->base_class.id == bc_modem
        )
      ) && hd->unix_dev_name
    ) {
      if(dev_name_duplicate(hd_data, hd->unix_dev_name)) continue;
      if((fd = open(hd->unix_dev_name, O_RDWR | O_NONBLOCK)) >= 0) {
        sm = add_ser_modem_entry(&hd_data->ser_modem, new_mem(sizeof *sm));
        sm->dev_name = new_str(hd->unix_dev_name);
        sm->fd = fd;
        sm->hd_idx = hd->idx;
        sm->do_io = 1;
        init_modem(sm);
      }
    }
  }

  if(!hd_data->ser_modem) return;

  PROGRESS(2, 0, "init");

  usleep(300000);		/* PnP protocol; 200ms seems to be too fast  */
  
  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    modem_info = TIOCM_DTR | TIOCM_RTS;
    ioctl(sm->fd, TIOCMBIS, &modem_info);
    ioctl(sm->fd, TIOCMGET, &modem_info);
    if(!(modem_info & (TIOCM_DSR | TIOCM_CD))) {
      sm->do_io = 0;
    }
  }

  /* just a quick test if we get a response to an AT command */

  for(i = 0; i < 4; i++) {
    PROGRESS(3, i + 1, "at test");

    for(sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(!sm->is_modem)
        set_modem_speed(sm, i == 0 ? 115200 : i == 1 ? 38400 : i == 2 ? 9600 : 1200);
    }

    at_cmd(hd_data, "AT\r", 1, 1);

    for(sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(strstr(sm->buf, "OK") || strstr(sm->buf, "0")) {
        sm->is_modem = 1;
        sm->do_io = 0;
      }
      sm->buf_len = 0;		/* clear buffer */
    }
  }

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if((sm->do_io = sm->is_modem)) {
      sm->max_baud = sm->cur_baud;
    }
  }

  /* check for init string */
  PROGRESS(4, 0, "init string");

  command = NULL;
  for(i = 0; (unsigned) i < MAX_INIT_STRING; i++) {
    str_printf(&command, 0, "AT %s\r", init_strings[i]);
    at_cmd(hd_data, command, 1, 1);

    for(sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(strstr(sm->buf, "OK") || strstr(sm->buf, "0")) {
        str_printf(&sm->init_string2, -1,
          "%s %s", sm->init_string2 ? "" : "AT", init_strings[i]
        );
      }
    }
  }
  command = free_mem(command);

  for(sm = hd_data->ser_modem; sm; sm = sm->next)
    if(sm->is_modem)
      str_printf(&sm->init_string1, -1, "ATZ");

  {
    int cmds[] = { 1, 3, 4, 5, 6 };
    char at[10];
    int i, j, ModemsCount = 0;
    str_list_t **responces = NULL;
    for(sm = hd_data->ser_modem; sm; sm = sm->next)
      if(sm->is_modem)
	ModemsCount++;
    responces = new_mem(ModemsCount * sizeof *responces);
    
    at_cmd(hd_data, "ATI\r", 0, 1);
    for(j = 0, sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(sm->is_modem)
	responces[j++] = str_list_dup(sm->at_resp);
    }

    for(i = 0; (unsigned) i < sizeof cmds / sizeof *cmds; i++) {
      int atx = cmds[i];
      sprintf(at, "ATI%d\r", atx);
      at_cmd(hd_data, at, 0, 1);
      for(j = 0, sm = hd_data->ser_modem; sm; sm = sm->next) {
	if(sm->is_modem) {
	  if(atx == 1 && check_for_responce(responces[j], "Hagenuk", 7) &&
	     (check_for_responce(sm->at_resp, "Speed Dragon", 12) ||
	      check_for_responce(sm->at_resp, "Power Dragon", 12))) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("ATB8");
	  }
	  if(atx == 3 && check_for_responce(responces[j], "346900", 6) &&
	     check_for_responce(sm->at_resp, "3Com U.S. Robotics ISDN", 23)) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("AT*PPP=1");
	  }
	  if(atx == 4 && check_for_responce(responces[j], "SP ISDN", 7) &&
	     check_for_responce(sm->at_resp, "Sportster ISDN TA", 17)) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("ATB3");
	  }
	  if(atx == 6 && check_for_responce(responces[j], "644", 3) &&
	     check_for_responce(sm->at_resp, "ELSA MicroLink ISDN", 19)) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("AT$IBP=HDLCP");
	    free_mem(sm->pppd_option);
	    sm->pppd_option = new_str("default-asyncmap");
	  }
	  if(atx == 6 && check_for_responce(responces[j], "643", 3) &&
	     check_for_responce(sm->at_resp, "MicroLink ISDN/TLV.34", 21)) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("AT\\N10%P1");
	  }
	  if(atx == 5 && check_for_responce(responces[j], "ISDN TA", 6) &&
	     check_for_responce(sm->at_resp, "ISDN TA;ASU", 4)) {
	    free_mem(sm->vend);
	    sm->vend = new_str("ASUS");
	    free_mem(sm->user_name);
	    sm->user_name = new_str("ISDNLink TA");
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("ATB40");
	  }
	  if(atx==3 && check_for_responce(responces[j], "128000", 6) &&
	     check_for_responce(sm->at_resp, "Lasat Speed", 11)) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("AT\\P1&B2X3");
	  }
	  if(atx == 1 &&
	     (check_for_responce(responces[j], "28642", 5) ||
	      check_for_responce(responces[j], "1281", 4) ||
	      check_for_responce(responces[j], "1282", 4) ||
	      check_for_responce(responces[j], "1283", 4) ||
	      check_for_responce(responces[j], "1291", 4) ||
	      check_for_responce(responces[j], "1292", 4) ||
	      check_for_responce(responces[j], "1293", 4)) &&
	     (check_for_responce(sm->at_resp, "Elite 2864I", 11) ||
	      check_for_responce(sm->at_resp, "ZyXEL omni", 10))) {
	    free_mem(sm->init_string1);
	    free_mem(sm->init_string2);
	    sm->init_string1 = new_str("AT&F");
	    sm->init_string2 = new_str("AT&O2B40");
	  }
	  j++;
	}
      }
    }

    for(i = 0; i < ModemsCount; i++) free_str_list(responces[i]);
    free_mem(responces);
  }

  /* now, go for the maximum speed... */
  PROGRESS(5, 0, "speed");

  for(i = MAX_SPEED - 1; i >= 0; i--) {
    baud = speeds[i].baud;
    for(j = 0, sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(sm->is_modem) {
        if(baud > sm->max_baud) {
          sm->do_io = set_modem_speed(sm, baud) ? 0 : 1;
          if(sm->do_io) j++;
        }
      }
    }

    /* no modems */
    if(!j) continue;

    at_cmd(hd_data, "AT\r", 1, 0);

    for(sm = hd_data->ser_modem; sm; sm = sm->next) {
      if(strstr(sm->buf, "OK") || strstr(sm->buf, "0")) {
        sm->max_baud = sm->cur_baud;
      }
      else {
        sm->do_io = 0;
      }
      sm->buf_len = 0;		/* clear buffer */
    }
  }

  /* now, fix it all up... */
  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->is_modem) {
      set_modem_speed(sm, sm->max_baud);
      sm->do_io = 1;
    }
  }

#if 0
  /* just for testing */
  if((hd_data->debug & HD_DEB_MODEM)) {
    int i;
    int cmds[] = { 0, 1, 2, 3, 6 };
    char at[10];

    PROGRESS(8, 0, "testing");

    at_cmd(hd_data, "ATI\r", 0, 1);
    for(i = 0; (unsigned) i < sizeof cmds / sizeof *cmds; i++) {
      sprintf(at, "ATI%d\r", cmds[i]);
      at_cmd(hd_data, at, 0, 1);
    }
    at_cmd(hd_data, "AT\r", 0, 1);
  }
#endif

  PROGRESS(5, 0, "pnp id");

  at_cmd(hd_data, "ATI9\r", 1, 1);

  for(sm = hd_data->ser_modem; sm; sm = sm->next) {
    if(sm->is_modem) {
      chk4id(sm);

      if(!sm->user_name) guess_modem_name(hd_data, sm);
    }

    /* reset serial lines */
    tcflush(sm->fd, TCIOFLUSH);
    tcsetattr(sm->fd, TCSAFLUSH, &sm->tio);
    close(sm->fd);
  }
}
예제 #22
0
파일: serial.c 프로젝트: dirkmueller/hwinfo
void hd_scan_serial(hd_data_t *hd_data)
{
  hd_t *hd, *hd2;
  serial_t *ser, *next;
  hd_res_t *res, *res2;
  int i;
  char buf[4], *skip_dev[16];
  str_list_t *sl, *cmd;
  unsigned skip_devs = 0;

  if(!hd_probe_feature(hd_data, pr_serial)) return;

  hd_data->module = mod_serial;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->serial = NULL;

  PROGRESS(1, 0, "read info");

  get_serial_info(hd_data);
  if((hd_data->debug & HD_DEB_SERIAL)) dump_serial_data(hd_data);

  for(i = 0; i < 2; i++) {
    cmd = get_cmdline(hd_data, i == 0 ? "yast2ser" : "console");
    for(sl = cmd; sl; sl = sl->next) {
      if(sscanf(sl->str, "tty%3[^,]", buf) == 1) {
        if(buf[1] == 0) {
          switch(*buf) {
            case 'a': strcpy(buf, "S0"); break;
            case 'b': strcpy(buf, "S1"); break;
          }
        }
        if(skip_devs < sizeof skip_dev / sizeof *skip_dev) {
          skip_dev[skip_devs] = NULL;
          str_printf(&skip_dev[skip_devs++], 0, "/dev/tty%s", buf);
        }
      }
    }
    free_str_list(cmd);
  }

  PROGRESS(2, 0, "build list");

  for(ser = hd_data->serial; ser; ser = ser->next) {
    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_comm;
    hd->sub_class.id = sc_com_ser;
    hd->prog_if.id = 0x80;
    for(i = 0; (unsigned) i < sizeof ser_names / sizeof *ser_names; i++) {
      if(strstr(ser->name, ser_names[i])) hd->prog_if.id = i;
    }
    hd->device.name = new_str(ser->name);
    hd->func = ser->line;
    if(ser->name && !strcmp(ser->name, "AgereModem")) {
      str_printf(&hd->unix_dev_name, 0, "/dev/ttyAGS%u", ser->line);
    }
    else {
      str_printf(&hd->unix_dev_name, 0, "/dev/ttyS%u", ser->line);
    }
    for(i = 0; i < (int) skip_devs; i++) {
      if(!strcmp(skip_dev[i], hd->unix_dev_name)) {
        hd->tag.skip_mouse = hd->tag.skip_modem = hd->tag.skip_braille = 1;
        break;
      }
    }
    if(ser->device) {
      if(strstr(ser->device, "modem-printer")) {
        hd->tag.ser_device = 1;
      }
      else if(strstr(ser->device, "infrared")) {
         hd->tag.ser_device = 2;
      }
      else if(strstr(ser->device, "modem")) {
         hd->tag.ser_device = 3;
      }
    }
    if(ser->baud) {
      res = add_res_entry(&hd->res, new_mem(sizeof *res));
      res->baud.type = res_baud;
      res->baud.speed = ser->baud;
    }
    res = add_res_entry(&hd->res, new_mem(sizeof *res));
    res->io.type = res_io;
    res->io.enabled = 1;
    res->io.base = ser->port;
    res->io.access = acc_rw;

    res = add_res_entry(&hd->res, new_mem(sizeof *res));
    res->irq.type = res_irq;
    res->irq.enabled = 1;
    res->irq.base = ser->irq;

    /* skip Dell Remote Access Cards - bug #145051 */
    for(hd2 = hd_data->hd; hd2; hd2 = hd2->next) {
      if(
        hd2->vendor.id == MAKE_ID(TAG_PCI, 0x1028) && /* Dell */
        hd2->device.id >= MAKE_ID(TAG_PCI, 0x07) &&
        hd2->device.id <= MAKE_ID(TAG_PCI, 0x12) /* range that covers DRACs */
      ) {
        for(res2 = hd2->res; res2; res2 = res2->next) {
          if(
            res2->any.type == res_io &&
            ser->port >= res2->io.base &&
            ser->port < res2->io.base + res2->io.range
          ) {
            hd->tag.skip_mouse = hd->tag.skip_modem = hd->tag.skip_braille = 1;
          }
        }
      }
    }
  }

  for(ser = hd_data->serial; ser; ser = next) {
    next = ser->next;

    free_mem(ser->name);
    free_mem(ser->device);
    free_mem(ser);
  }
  hd_data->serial = NULL;

#if 0
  if(hd_module_is_active(hd_data, "irda")) {
    hd = add_hd_entry(hd_data, __LINE__, 0); 
    hd->base_class.id = bc_comm;
    hd->sub_class.id = sc_com_ser;
    hd->prog_if.id = 0x80;
    hd->device.name = new_str("IrDA Serial");
    hd->unix_dev_name = new_str("/dev/ircomm0");
  }
#endif
}
예제 #23
0
파일: serial.c 프로젝트: dirkmueller/hwinfo
void get_serial_info(hd_data_t *hd_data)
{
  char buf[64];
  unsigned u0, u1, u2;
#if !defined(__PPC__)
  unsigned u3;
#endif
  int i;
  str_list_t *sl, *sl0, **sll;
  serial_t *ser;

#if !defined(__PPC__)
  /*
   * Max. 44 serial lines at the moment; the serial proc interface is
   * somewhat buggy at the moment (2.2.13), hence the explicit 44 lines
   * limit. That may be dropped later.
   */
  sl0 = read_file(PROC_DRIVER_SERIAL, 1, 44);
  sll = &sl0;
  while(*sll) sll = &(*sll)->next;
  // append Agere modem devices
  *sll = read_file("/proc/tty/driver/agrserial", 1, 17);


  // ########## FIX !!!!!!!! ########
  if(sl0) {
    for(sl = sl0; sl; sl = sl->next) {
      i = 0;
      if(
        sscanf(sl->str, "%u: uart:%31s port:%x irq:%u baud:%u", &u0, buf, &u1, &u2, &u3) == 5 ||
        (i = 1, sscanf(sl->str, "%u: uart:%31s port:%x irq:%u tx:%u", &u0, buf, &u1, &u2, &u3) == 5)
      ) {
        /*
         * The 'baud' or 'tx' entries are only present for real interfaces.
         */
        ser = add_serial_entry(&hd_data->serial, new_mem(sizeof *ser));
        ser->line = u0;
        if(u1 >= 0x100) ser->port = u1;		// Agere modem does not use real port numbers
        ser->irq = u2;
        if(!i) ser->baud = u3;
        ser->name = new_str(buf);
      }
    }

    if((hd_data->debug & HD_DEB_SERIAL)) {
      /* log just the first 16 entries */
      ADD2LOG("----- "PROC_DRIVER_SERIAL" -----\n");
      for(sl = sl0, i = 16; sl && i--; sl = sl->next) {
        ADD2LOG("  %s", sl->str);
      }
      ADD2LOG("----- "PROC_DRIVER_SERIAL" end -----\n");
    }
  }
#endif	/* !defined(__PPC__) */

#if defined(__PPC__)
  sl0 = read_file(PROC_DRIVER_MACSERIAL, 1, 0);

  if(sl0) {
    for(sl = sl0; sl; sl = sl->next) {
      if(
        (i = sscanf(sl->str, "%u: port:%x irq:%u con:%63[^\n]", &u0, &u1, &u2, buf)) >= 3
      ) {
        ser = add_serial_entry(&hd_data->serial, new_mem(sizeof *ser));
        ser->line = u0;
        ser->port = u1;
        ser->irq = u2;
        ser->name = new_str("SCC");
        if(i == 4) ser->device = new_str(buf);
      }
    }

    if((hd_data->debug & HD_DEB_SERIAL)) {
      /* log just the first 16 entries */
      ADD2LOG("----- "PROC_DRIVER_MACSERIAL" -----\n");
      for(sl = sl0, i = 16; sl && i--; sl = sl->next) {
        ADD2LOG("  %s", sl->str);
      }
      ADD2LOG("----- "PROC_DRIVER_MACSERIAL" end -----\n");
    }
  }
#endif	/* defined(__PPC__) */


  free_str_list(sl0);
}
예제 #24
0
/* FIXME: Cleanup track refs */
void common_cleanup(struct con_win *cwin)
{
	CDEBUG(DBG_INFO, "Cleaning up");

	if ((cwin->cstate->state == ST_STOPPED) && (cwin->cstate->curr_mobj_clear))
		delete_musicobject(cwin->cstate->curr_mobj);

	if ((cwin->cstate->state == ST_PLAYING) || (cwin->cstate->state == ST_PAUSED))
		stop_playback(cwin);

	save_preferences(cwin);

	g_object_unref(cwin->library_store);
	g_object_unref(cwin->pixbuf->image_play);
	g_object_unref(cwin->pixbuf->image_pause);

	if (cwin->pixbuf->pixbuf_app)
		g_object_unref(cwin->pixbuf->pixbuf_app);
	if (cwin->pixbuf->pixbuf_dir)
		g_object_unref(cwin->pixbuf->pixbuf_dir);
	if (cwin->pixbuf->pixbuf_artist)
		g_object_unref(cwin->pixbuf->pixbuf_artist);
	if (cwin->pixbuf->pixbuf_album)
		g_object_unref(cwin->pixbuf->pixbuf_album);
	if (cwin->pixbuf->pixbuf_track)
		g_object_unref(cwin->pixbuf->pixbuf_track);
	if (cwin->pixbuf->pixbuf_genre)
		g_object_unref(cwin->pixbuf->pixbuf_genre);

	g_slice_free(struct pixbuf, cwin->pixbuf);

	if (cwin->album_art)
		gtk_widget_destroy(cwin->album_art);

	if (cwin->cstate->cdda_drive)
		cdio_cddap_close(cwin->cstate->cdda_drive);
	if (cwin->cstate->cddb_disc)
		cddb_disc_destroy(cwin->cstate->cddb_disc);
	if (cwin->cstate->cddb_conn) {
		cddb_destroy(cwin->cstate->cddb_conn);
		libcddb_shutdown();
	}

	g_free(cwin->cpref->lw.lastfm_user);
	g_free(cwin->cpref->lw.lastfm_pass);
#ifdef HAVE_LIBGLYR
	g_free(cwin->cpref->cache_folder);
#endif
	g_free(cwin->cpref->configrc_file);
	g_free(cwin->cpref->installed_version);
	g_free(cwin->cpref->audio_sink);
	g_free(cwin->cpref->audio_alsa_device);
	g_free(cwin->cpref->audio_oss_device);
	g_free(cwin->cpref->album_art_pattern);
	g_free(cwin->cpref->audio_cd_device);
	g_free(cwin->cpref->start_mode);
	g_free(cwin->cpref->sidebar_pane);
	g_key_file_free(cwin->cpref->configrc_keyfile);
	free_str_list(cwin->cpref->library_dir);
	free_str_list(cwin->cpref->lib_add);
	free_str_list(cwin->cpref->lib_delete);
	free_str_list(cwin->cpref->library_tree_nodes);
	free_str_list(cwin->cpref->playlist_columns);
	g_slist_free(cwin->cpref->playlist_column_widths);
	g_slice_free(struct con_pref, cwin->cpref);

	g_rand_free(cwin->cstate->rand);
	g_free(cwin->cstate->last_folder);
	g_mutex_free(cwin->cstate->c_mutex);

	/* Hack, hack */
	if (g_mutex_trylock(cwin->cstate->l_mutex) == TRUE) {
		g_mutex_unlock(cwin->cstate->l_mutex);
		g_mutex_free(cwin->cstate->l_mutex);
	}
	g_cond_free(cwin->cstate->c_cond);
	g_slice_free(struct con_state, cwin->cstate);

#ifdef HAVE_LIBGLYR
	uninit_glyr_related (cwin);
#endif
	g_free(cwin->cdbase->db_file);
	sqlite3_close(cwin->cdbase->db);
	g_slice_free(struct con_dbase, cwin->cdbase);

	if (cwin->cstate->audio_init && cwin->cmixer)
		cwin->cmixer->deinit_mixer(cwin);
	if (cwin->clibao->ao_dev) {
		CDEBUG(DBG_INFO, "Freeing ao dev");
		ao_close(cwin->clibao->ao_dev);
	}
	ao_shutdown();
	g_slice_free(struct con_mixer, cwin->cmixer);
	g_slice_free(struct con_libao, cwin->clibao);

	g_free(cwin->clastfm->session_id);
	g_free(cwin->clastfm->submission_url);
	if (cwin->clastfm->curl_handle)
		curl_easy_cleanup(cwin->clastfm->curl_handle);
	curl_global_cleanup();
	g_slice_free(struct con_lastfm, cwin->clastfm);

	dbus_connection_remove_filter(cwin->con_dbus,
				      dbus_filter_handler,
				      cwin);
	dbus_bus_remove_match(cwin->con_dbus,
			      "type='signal',path='/org/pragha/DBus'",
			      NULL);
	dbus_connection_unref(cwin->con_dbus);

	#if HAVE_GLIB_2_26
	mpris_cleanup(cwin);
	#endif

	if (notify_is_initted())
		notify_uninit();

	#ifdef HAVE_LIBKEYBINDER
	keybinder_unbind("XF86AudioPlay", (KeybinderHandler) keybind_play_handler);
	keybinder_unbind("XF86AudioStop", (KeybinderHandler) keybind_stop_handler);
	keybinder_unbind("XF86AudioPrev", (KeybinderHandler) keybind_prev_handler);
	keybinder_unbind("XF86AudioNext", (KeybinderHandler) keybind_next_handler);
	keybinder_unbind("XF86AudioMedia", (KeybinderHandler) keybind_media_handler);
	#endif

	g_option_context_free(cwin->cmd_context);

	g_slice_free(struct con_win, cwin);
}
예제 #25
0
파일: pci.c 프로젝트: jakeogh/hwinfo
/*
 * Get the (raw) PCI data, taken from /sys/bus/pci.
 *
 * Note: non-root users can only read the first 64 bytes (of 256)
 * of the device headers.
 */
void hd_pci_read_data(hd_data_t *hd_data)
{
  uint64_t ul0, ul1, ul2;
  unsigned u, u0, u1, u2, u3;
  unsigned char nxt;
  str_list_t *sl;
  char *s;
  pci_t *pci;
  int fd;
  str_list_t *sf_bus, *sf_bus_e, *sf_drm_dirs, *sf_drm_dir, *sf_drm_subdirs,
    *sf_drm_subdir;
  char *sf_dev, *sf_drm = NULL, *sf_drm_subpath = NULL, *sf_drm_edid = NULL;

  sf_bus = read_dir("/sys/bus/pci/devices", 'l');

  if(!sf_bus) {
    ADD2LOG("sysfs: no such bus: pci\n");
    return;
  }

  for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) {
    sf_dev = new_str(hd_read_sysfs_link("/sys/bus/pci/devices", sf_bus_e->str));

    ADD2LOG(
      "  pci device: name = %s\n    path = %s\n",
      sf_bus_e->str,
      hd_sysfs_id(sf_dev)
    );

    if(sscanf(sf_bus_e->str, "%x:%x:%x.%x", &u0, &u1, &u2, &u3) != 4) continue;

    pci = add_pci_entry(hd_data, new_mem(sizeof *pci));

    pci->sysfs_id = new_str(sf_dev);
    pci->sysfs_bus_id = new_str(sf_bus_e->str);

    pci->bus = (u0 << 8) + u1;
    pci->slot = u2;
    pci->func = u3;

    if((s = get_sysfs_attr_by_path(sf_dev, "modalias"))) {
      pci->modalias = canon_str(s, strlen(s));
      ADD2LOG("    modalias = \"%s\"\n", pci->modalias);
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "class"), &ul0, 0)) {
      ADD2LOG("    class = 0x%x\n", (unsigned) ul0);
      pci->prog_if = ul0 & 0xff;
      pci->sub_class = (ul0 >> 8) & 0xff;
      pci->base_class = (ul0 >> 16) & 0xff;
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "vendor"), &ul0, 0)) {
      ADD2LOG("    vendor = 0x%x\n", (unsigned) ul0);
      pci->vend = ul0 & 0xffff;
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "device"), &ul0, 0)) {
      ADD2LOG("    device = 0x%x\n", (unsigned) ul0);
      pci->dev = ul0 & 0xffff;
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "subsystem_vendor"), &ul0, 0)) {
      ADD2LOG("    subvendor = 0x%x\n", (unsigned) ul0);
      pci->sub_vend = ul0 & 0xffff;
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "subsystem_device"), &ul0, 0)) {
      ADD2LOG("    subdevice = 0x%x\n", (unsigned) ul0);
      pci->sub_dev = ul0 & 0xffff;
    }

    if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "irq"), &ul0, 0)) {
      ADD2LOG("    irq = %d\n", (unsigned) ul0);
      pci->irq = ul0;
    }

    if((s = get_sysfs_attr_by_path(sf_dev, "label"))) {
      pci->label = canon_str(s, strlen(s));
      ADD2LOG("    label = \"%s\"\n", pci->label);
    }

    sl = hd_attr_list(get_sysfs_attr_by_path(sf_dev, "resource"));
    for(u = 0; sl; sl = sl->next, u++) {
      if(
        sscanf(sl->str, "0x%"SCNx64" 0x%"SCNx64" 0x%"SCNx64, &ul0, &ul1, &ul2) == 3 &&
        ul1 &&
        u < sizeof pci->base_addr / sizeof *pci->base_addr
      ) {
        ADD2LOG("    res[%u] = 0x%"PRIx64" 0x%"PRIx64" 0x%"PRIx64"\n", u, ul0, ul1, ul2);
        pci->base_addr[u] = ul0;
        pci->base_len[u] = ul1 + 1 - ul0;
        pci->addr_flags[u] = ul2;
      }
    }

    s = NULL;
    str_printf(&s, 0, "%s/config", sf_dev);
    if((fd = open(s, O_RDONLY)) != -1) {
      pci->data_len = pci->data_ext_len = read(fd, pci->data, 0x40);
      ADD2LOG("    config[%u]\n", pci->data_len);

      if(pci->data_len >= 0x40) {
        pci->hdr_type = pci->data[PCI_HEADER_TYPE] & 0x7f;
        pci->cmd = pci->data[PCI_COMMAND] + (pci->data[PCI_COMMAND + 1] << 8);

        if(pci->hdr_type == 1 || pci->hdr_type == 2) {	/* PCI or CB bridge */
          pci->secondary_bus = pci->data[PCI_SECONDARY_BUS];
          /* PCI_SECONDARY_BUS == PCI_CB_CARD_BUS */
        }

        for(u = 0; u < sizeof pci->base_addr / sizeof *pci->base_addr; u++) {
          if((pci->addr_flags[u] & IORESOURCE_IO)) {
            if(!(pci->cmd & PCI_COMMAND_IO)) pci->addr_flags[u] |= IORESOURCE_DISABLED;
          }

          if((pci->addr_flags[u] & IORESOURCE_MEM)) {
            if(!(pci->cmd & PCI_COMMAND_MEMORY)) pci->addr_flags[u] |= IORESOURCE_DISABLED;
          }
        }

        /* let's go through the capability list */
        if(
          pci->hdr_type == PCI_HEADER_TYPE_NORMAL &&
          (nxt = pci->data[PCI_CAPABILITY_LIST])
        ) {
          /*
           * Cut out after 16 capabilities to avoid infinite recursion due
           * to (potentially) malformed data. 16 is more or less
           * arbitrary, though (the capabilities are bits in a byte, so 8 entries
           * should suffice).
           */
          for(u = 0; u < 16 && nxt && nxt <= 0xfe; u++) {
            switch(pci_cfg_byte(pci, fd, nxt)) {
              case PCI_CAP_ID_PM:
                pci->flags |= (1 << pci_flag_pm);
                break;

              case PCI_CAP_ID_AGP:
                pci->flags |= (1 << pci_flag_agp);
                break;
            }
            nxt = pci_cfg_byte(pci, fd, nxt + 1);
          }
        }
      }

      close(fd);
    }

    /* FIXME: stil valid? */
    for(u = 0; u < sizeof pci->edid_len / sizeof *pci->edid_len; u++) {
      str_printf(&s, 0, "%s/edid%u", sf_dev, u + 1);
      add_edid_from_file(s, pci, u, hd_data);
    }
    s = free_mem(s);

    /* try searching the monitor data in <PCI_dev>/drm/x/x/edid files if no data found*/
    if (pci->edid_len[0] == 0) {
      str_printf(&sf_drm, 0, "%s/drm", sf_dev);
      u = 0;

      /* get <PCI_dev>/drm/x listing */
      sf_drm_dirs = read_dir(sf_drm, 'd');
      for(sf_drm_dir = sf_drm_dirs; sf_drm_dir; sf_drm_dir = sf_drm_dir->next) {
        str_printf(&sf_drm_subpath, 0, "%s/drm/%s", sf_dev, sf_drm_dir->str);

        /* get <PCI_dev>/drm/x/x listing */
        sf_drm_subdirs = read_dir(sf_drm_subpath, 'd');
        for(sf_drm_subdir = sf_drm_subdirs; sf_drm_subdir; sf_drm_subdir = sf_drm_subdir->next) {
          /* try loading <PCI_dev>/drm/x/x/edid file */
          str_printf(&sf_drm_edid, 0, "%s/%s/edid", sf_drm_subpath, sf_drm_subdir->str);
          add_edid_from_file(sf_drm_edid, pci, u, hd_data);

          if (pci->edid_len[u] > 0) {
            u = u + 1;
          }
        }

        free_str_list(sf_drm_subdirs);
      }

      sf_drm_subpath = free_mem(sf_drm_subpath);
      sf_drm_edid = free_mem(sf_drm_edid);
      sf_drm = free_mem(sf_drm);
      free_str_list(sf_drm_dirs);
    }

    pci->rev = pci->data[PCI_REVISION_ID];

    if((pci->addr_flags[6] & IORESOURCE_MEM)) {
      if(!(pci->data[PCI_ROM_ADDRESS] & PCI_ROM_ADDRESS_ENABLE)) {
        pci->addr_flags[6] |= IORESOURCE_DISABLED;
      }
    }

    pci->flags |= (1 << pci_flag_ok);

    free_mem(sf_dev);
  }
예제 #26
0
파일: transact.c 프로젝트: aosm/fetchmail
int readheaders(int sock,
		       long fetchlen,
		       long reallen,
		       struct query *ctl,
		       int num,
		       flag *suppress_readbody)
/* read message headers and ship to SMTP or MDA */
/*   sock:		to which the server is connected */
/*   fetchlen:		length of message according to fetch response */
/*   reallen:		length of message according to getsizes */
/*   ctl:		query control record */
/*   num:		index of message */
/*   suppress_readbody:	whether call to readbody() should be supressed */
{
    struct addrblk
    {
	int		offset;
	struct addrblk	*next;
    };
    struct addrblk	*to_addrchain = NULL;
    struct addrblk	**to_chainptr = &to_addrchain;
    struct addrblk	*resent_to_addrchain = NULL;
    struct addrblk	**resent_to_chainptr = &resent_to_addrchain;

    char		buf[MSGBUFSIZE+1];
    int			from_offs, reply_to_offs, resent_from_offs;
    int			app_from_offs, sender_offs, resent_sender_offs;
    int			env_offs;
    char		*received_for, *rcv, *cp;
    static char		*delivered_to = NULL;
    int 		n, oldlen, ch, remaining, skipcount;
    size_t		linelen;
    int			delivered_to_count;
    struct idlist 	*idp;
    flag		no_local_matches = FALSE;
    flag		has_nuls;
    int			olderrs, good_addresses, bad_addresses;
    int			retain_mail = 0, refuse_mail = 0;
    flag		already_has_return_path = FALSE;

    sizeticker = 0;
    has_nuls = FALSE;
    msgblk.return_path[0] = '\0';
    olderrs = ctl->errcount;

    /* read message headers */
    msgblk.reallen = reallen;

    /*
     * We used to free the header block unconditionally at the end of 
     * readheaders, but it turns out that if close_sink() hits an error
     * condition the code for sending bouncemail will actually look
     * at the freed storage and coredump...
     */
    xfree(msgblk.headers);
    free_str_list(&msgblk.recipients);
    xfree(delivered_to);

    /* initially, no message digest */
    memset(ctl->digest, '\0', sizeof(ctl->digest));

    received_for = NULL;
    from_offs = reply_to_offs = resent_from_offs = app_from_offs = 
	sender_offs = resent_sender_offs = env_offs = -1;
    oldlen = 0;
    msgblk.msglen = 0;
    skipcount = 0;
    delivered_to_count = 0;
    ctl->mimemsg = 0;

    for (remaining = fetchlen; remaining > 0 || protocol->delimited; )
    {
	char *line, *rline;

	line = (char *)xmalloc(sizeof(buf));
	linelen = 0;
	line[0] = '\0';
	do {
	    do {
		char	*sp, *tp;

		set_timeout(mytimeout);
		if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) {
		    set_timeout(0);
		    free(line);
		    return(PS_SOCKET);
		}
		set_timeout(0);

		/*
		 * Smash out any NULs, they could wreak havoc later on.
		 * Some network stacks seem to generate these at random,
		 * especially (according to reports) at the beginning of the
		 * first read.  NULs are illegal in RFC822 format.
		 */
		for (sp = tp = buf; sp < buf + n; sp++)
		    if (*sp)
			*tp++ = *sp;
		*tp = '\0';
		n = tp - buf;
	    } while
		  (n == 0);

	    remaining -= n;
	    linelen += n;
	    msgblk.msglen += n;

	    /*
	     * Try to gracefully handle the case where the length of a
	     * line exceeds MSGBUFSIZE.
	     */
	    if (n && buf[n-1] != '\n') 
	    {
		rline = (char *) realloc(line, linelen + 1);
		if (rline == NULL)
		{
		    free (line);
		    return(PS_IOERR);
		}
		line = rline;
		memcpy(line + linelen - n, buf, n);
		line[linelen] = '\0';
		ch = ' '; /* So the next iteration starts */
		continue;
	    }

	    /* lines may not be properly CRLF terminated; fix this for qmail */
	    /* we don't want to overflow the buffer here */
	    if (ctl->forcecr && buf[n-1]=='\n' && (n==1 || buf[n-2]!='\r'))
	    {
		char * tcp;
		rline = (char *) realloc(line, linelen + 2);
		if (rline == NULL)
		{
		    free (line);
		    return(PS_IOERR);
		}
		line = rline;
		memcpy(line + linelen - n, buf, n - 1);
		tcp = line + linelen - 1;
		*tcp++ = '\r';
		*tcp++ = '\n';
		*tcp = '\0';
		/* n++; - not used later on */
		linelen++;
	    }
	    else
	    {
		rline = (char *) realloc(line, linelen + 1);
		if (rline == NULL)
		{
		    free (line);
		    return(PS_IOERR);
		}
		line = rline;
		memcpy(line + linelen - n, buf, n + 1);
	    }

	    /* check for end of headers */
	    if (end_of_header(line))
	    {
eoh:
		if (linelen != strlen (line))
		    has_nuls = TRUE;
		free(line);
		goto process_headers;
	    }

	    /*
	     * Check for end of message immediately.  If one of your folders
	     * has been mangled, the delimiter may occur directly after the
	     * header.
	     */
	    if (protocol->delimited && line[0] == '.' && EMPTYLINE(line+1))
	    {
		if (suppress_readbody)
		    *suppress_readbody = TRUE;
		goto eoh; /* above */
	    }

	    /*
	     * At least one brain-dead website (netmind.com) is known to
	     * send out robotmail that's missing the RFC822 delimiter blank
	     * line before the body! Without this check fetchmail segfaults.
	     * With it, we treat such messages as spam and refuse them.
	     *
	     * Frederic Marchal reported in February 2006 that hotmail
	     * or something improperly wrapped a very long TO header
	     * (wrapped without inserting whitespace in the continuation
	     * line) and found that this code thus refused a message
	     * that should have been delivered.
	     *
	     * XXX FIXME: we should probably wrap the message up as
	     * message/rfc822 attachment and forward to postmaster (Rob
	     * MacGregor)
	     */
	    if (!refuse_mail
		&& !ctl->server.badheader == BHACCEPT
		&& !isspace((unsigned char)line[0])
		&& !strchr(line, ':'))
	    {
		if (linelen != strlen (line))
		    has_nuls = TRUE;
		if (outlevel > O_SILENT)
		    report(stdout,
			   GT_("incorrect header line found - see manpage for bad-header option\n"));
		if (outlevel >= O_VERBOSE)
		    report (stdout, GT_("line: %s"), line);
		refuse_mail = 1;
	    }

	    /* check for RFC822 continuations */
	    set_timeout(mytimeout);
	    ch = SockPeek(sock);
	    set_timeout(0);
	} while
	    (ch == ' ' || ch == '\t');	/* continuation to next line? */

	/* write the message size dots */
	if ((outlevel > O_SILENT && outlevel < O_VERBOSE) && linelen > 0)
	{
	    print_ticker(&sizeticker, linelen);
	}

	/*
	 * Decode MIME encoded headers. We MUST do this before
	 * looking at the Content-Type / Content-Transfer-Encoding
	 * headers (RFC 2046).
	 */
	if ( ctl->mimedecode )
	{
	    char *tcp;
	    UnMimeHeader(line);
	    /* the line is now shorter. So we retrace back till we find
	     * our terminating combination \n\0, we move backwards to
	     * make sure that we don't catch some \n\0 stored in the
	     * decoded part of the message */
	    for (tcp = line + linelen - 1; tcp > line && (*tcp != 0 || tcp[-1] != '\n'); tcp--);
	    if  (tcp > line) linelen = tcp - line;
	}


	/* skip processing if we are going to retain or refuse this mail */
	if (retain_mail || refuse_mail)
	{
	    free(line);
	    continue;
	}

	/* we see an ordinary (non-header, non-message-delimiter) line */
	if (linelen != strlen (line))
	    has_nuls = TRUE;

	/*
	 * The University of Washington IMAP server (the reference
	 * implementation of IMAP4 written by Mark Crispin) relies
	 * on being able to keep base-UID information in a special
	 * message at the head of the mailbox.  This message should
	 * neither be deleted nor forwarded.
	 *
	 * An example for such a message is (keep this in so people
	 * find it when looking where the special code is to handle the
	 * data):
	 *
	 *   From MAILER-DAEMON Wed Nov 23 11:38:42 2005
	 *   Date: 23 Nov 2005 11:38:42 +0100
	 *   From: Mail System Internal Data <*****@*****.**>
	 *   Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
	 *   Message-ID: <*****@*****.**>
	 *   X-IMAP: 1132742306 0000000001
	 *   Status: RO
	 *
	 *   This text is part of the internal format of your mail folder, and is not
	 *   a real message.  It is created automatically by the mail system software.
	 *   If deleted, important folder data will be lost, and it will be re-created
	 *   with the data reset to initial values.
	 *
	 * This message is only visible if a POP3 server that is unaware
	 * of these UWIMAP messages is used besides UWIMAP or PINE.
	 *
	 * We will just check if the first message in the mailbox has an
	 * X-IMAP: header.
	 */
#ifdef POP2_ENABLE
	/*
	 * We disable this check under POP2 because there's no way to
	 * prevent deletion of the message.  So at least we ought to
	 * forward it to the user so he or she will have some clue
	 * that things have gone awry.
	 */
	if (servport("pop2") != servport(protocol->service))
#endif /* POP2_ENABLE */
	    if (num == 1 && !strncasecmp(line, "X-IMAP:", 7)) {
		free(line);
		retain_mail = 1;
		continue;
	    }

	/*
	 * This code prevents fetchmail from becoming an accessory after
	 * the fact to upstream sendmails with the `E' option on.  It also
	 * copes with certain brain-dead POP servers (like NT's) that pass
	 * through Unix from_ lines.
	 *
	 * Either of these bugs can result in a non-RFC822 line at the
	 * beginning of the headers.  If fetchmail just passes it
	 * through, the client listener may think the message has *no*
	 * headers (since the first) line it sees doesn't look
	 * RFC822-conformant) and fake up a set.
	 *
	 * What the user would see in this case is bogus (synthesized)
	 * headers, followed by a blank line, followed by the >From, 
	 * followed by the real headers, followed by a blank line,
	 * followed by text.
	 *
	 * We forestall this lossage by tossing anything that looks
	 * like an escaped or passed-through From_ line in headers.
	 * These aren't RFC822 so our conscience is clear...
	 */
	if (!strncasecmp(line, ">From ", 6) || !strncasecmp(line, "From ", 5))
	{
	    free(line);
	    continue;
	}

	/*
	 * We remove all Delivered-To: headers if dropdelivered is set
	 * - special care must be taken if Delivered-To: is also used
	 * as envelope at the same time.
	 *
	 * This is to avoid false mail loops errors when delivering
	 * local messages to and from a Postfix or qmail mailserver.
	 */
	if (ctl->dropdelivered && !strncasecmp(line, "Delivered-To:", 13)) 
	{
	    if (delivered_to ||
	    	ctl->server.envelope == STRING_DISABLED ||
		!ctl->server.envelope ||
		strcasecmp(ctl->server.envelope, "Delivered-To") ||
		delivered_to_count != ctl->server.envskip)
		free(line);
	    else 
		delivered_to = line;
	    delivered_to_count++;
	    continue;
	}

	/*
	 * If we see a Status line, it may have been inserted by an MUA
	 * on the mail host, or it may have been inserted by the server
	 * program after the headers in the transaction stream.  This
	 * can actually hose some new-mail notifiers such as xbuffy,
	 * which assumes any Status line came from a *local* MDA and
	 * therefore indicates that the message has been seen.
	 *
	 * Some buggy POP servers (including at least the 3.3(20)
	 * version of the one distributed with IMAP) insert empty
	 * Status lines in the transaction stream; we'll chuck those
	 * unconditionally.  Nonempty ones get chucked if the user
	 * turns on the dropstatus flag.
	 */
	{
	    char	*tcp;

	    if (!strncasecmp(line, "Status:", 7))
		tcp = line + 7;
	    else if (!strncasecmp(line, "X-Mozilla-Status:", 17))
		tcp = line + 17;
	    else
		tcp = NULL;
	    if (tcp) {
		while (*tcp && isspace((unsigned char)*tcp)) tcp++;
		if (!*tcp || ctl->dropstatus)
		{
		    free(line);
		    continue;
		}
	    }
	}

	if (ctl->rewrite)
	    line = reply_hack(line, ctl->server.truename, &linelen);

	/*
	 * OK, this is messy.  If we're forwarding by SMTP, it's the
	 * SMTP-receiver's job (according to RFC821, page 22, section
	 * 4.1.1) to generate a Return-Path line on final delivery.
	 * The trouble is, we've already got one because the
	 * mailserver's SMTP thought *it* was responsible for final
	 * delivery.
	 *
	 * Stash away the contents of Return-Path (as modified by reply_hack)
	 * for use in generating MAIL FROM later on, then prevent the header
	 * from being saved with the others.  In effect, we strip it off here.
	 *
	 * If the SMTP server conforms to the standards, and fetchmail gets the
	 * envelope sender from the Return-Path, the new Return-Path should be
	 * exactly the same as the original one.
	 *
	 * We do *not* want to ignore empty Return-Path headers.  These should
	 * be passed through as a way of indicating that a message should
	 * not trigger bounces if delivery fails.  What we *do* need to do is
	 * make sure we never try to rewrite such a blank Return-Path.  We
	 * handle this with a check for <> in the rewrite logic above.
	 *
	 * Also, if an email has multiple Return-Path: headers, we only
	 * read the first occurance, as some spam email has more than one
	 * Return-Path.
	 *
	 */
	if ((already_has_return_path==FALSE) && !strncasecmp("Return-Path:", line, 12) && (cp = nxtaddr(line)))
	{
	    char nulladdr[] = "<>";
	    already_has_return_path = TRUE;
	    if (cp[0]=='\0')	/* nxtaddr() strips the brackets... */
		cp=nulladdr;
	    strncpy(msgblk.return_path, cp, sizeof(msgblk.return_path));
	    msgblk.return_path[sizeof(msgblk.return_path)-1] = '\0';
	    if (!ctl->mda) {
		free(line);
		continue;
	    }
	}

	if (!msgblk.headers)
	{
	    oldlen = linelen;
	    msgblk.headers = (char *)xmalloc(oldlen + 1);
	    (void) memcpy(msgblk.headers, line, linelen);
	    msgblk.headers[oldlen] = '\0';
	    free(line);
	    line = msgblk.headers;
	}
	else
	{
	    char *newhdrs;
	    int	newlen;

	    newlen = oldlen + linelen;
	    newhdrs = (char *) realloc(msgblk.headers, newlen + 1);
	    if (newhdrs == NULL) {
		free(line);
		return(PS_IOERR);
	    }
	    msgblk.headers = newhdrs;
	    memcpy(msgblk.headers + oldlen, line, linelen);
	    msgblk.headers[newlen] = '\0';
	    free(line);
	    line = msgblk.headers + oldlen;
	    oldlen = newlen;
	}

	/* find offsets of various special headers */
	if (!strncasecmp("From:", line, 5))
	    from_offs = (line - msgblk.headers);
	else if (!strncasecmp("Reply-To:", line, 9))
	    reply_to_offs = (line - msgblk.headers);
	else if (!strncasecmp("Resent-From:", line, 12))
	    resent_from_offs = (line - msgblk.headers);
	else if (!strncasecmp("Apparently-From:", line, 16))
	    app_from_offs = (line - msgblk.headers);
	/*
	 * Netscape 4.7 puts "Sender: zap" in mail headers.  Perverse...
	 *
	 * But a literal reading of RFC822 sec. 4.4.2 supports the idea
	 * that Sender: *doesn't* have to be a working email address.
	 *
	 * The definition of the Sender header in RFC822 says, in
	 * part, "The Sender mailbox specification includes a word
	 * sequence which must correspond to a specific agent (i.e., a
	 * human user or a computer program) rather than a standard
	 * address."  That implies that the contents of the Sender
	 * field don't need to be a legal email address at all So
	 * ignore any Sender or Resent-Sender lines unless they
	 * contain @.
	 *
	 * (RFC2822 says the contents of Sender must be a valid mailbox
	 * address, which is also what RFC822 4.4.4 implies.)
	 */
	else if (!strncasecmp("Sender:", line, 7) && (strchr(line, '@') || strchr(line, '!')))
	    sender_offs = (line - msgblk.headers);
	else if (!strncasecmp("Resent-Sender:", line, 14) && (strchr(line, '@') || strchr(line, '!')))
	    resent_sender_offs = (line - msgblk.headers);

#ifdef __UNUSED__
 	else if (!strncasecmp("Message-Id:", line, 11))
	{
	    if (ctl->server.uidl)
 	    {
	        char id[IDLEN+1];

		line[IDLEN+12] = 0;		/* prevent stack overflow */
 		sscanf(line+12, "%s", id);
 	        if (!str_find( &ctl->newsaved, num))
		{
 		    struct idlist *newl = save_str(&ctl->newsaved,id,UID_SEEN);
		    newl->val.status.num = num;
		}
 	    }
 	}
#endif /* __UNUSED__ */

	/* if multidrop is on, gather addressee headers */
	if (MULTIDROP(ctl))
	{
	    if (!strncasecmp("To:", line, 3)
		|| !strncasecmp("Cc:", line, 3)
		|| !strncasecmp("Bcc:", line, 4)
		|| !strncasecmp("Apparently-To:", line, 14))
	    {
		*to_chainptr = (struct addrblk *)xmalloc(sizeof(struct addrblk));
		(*to_chainptr)->offset = (line - msgblk.headers);
		to_chainptr = &(*to_chainptr)->next; 
		*to_chainptr = NULL;
	    }

	    else if (!strncasecmp("Resent-To:", line, 10)
		     || !strncasecmp("Resent-Cc:", line, 10)
		     || !strncasecmp("Resent-Bcc:", line, 11))
	    {
		*resent_to_chainptr = (struct addrblk *)xmalloc(sizeof(struct addrblk));
		(*resent_to_chainptr)->offset = (line - msgblk.headers);
		resent_to_chainptr = &(*resent_to_chainptr)->next; 
		*resent_to_chainptr = NULL;
	    }

	    else if (ctl->server.envelope != STRING_DISABLED)
	    {
		if (ctl->server.envelope 
		    && strcasecmp(ctl->server.envelope, "Received"))
		{
		    if (env_offs == -1 && !strncasecmp(ctl->server.envelope,
						       line,
						       strlen(ctl->server.envelope)))
		    {				
			if (skipcount++ < ctl->server.envskip)
			    continue;
			env_offs = (line - msgblk.headers);
		    }    
		}
		else if (!received_for && !strncasecmp("Received:", line, 9))
		{
		    if (skipcount++ < ctl->server.envskip)
			continue;
		    received_for = parse_received(ctl, line);
		}
	    }
	}
    }

process_headers:

    if (retain_mail) {
	return(PS_RETAINED);
    }

    if (refuse_mail)
	return(PS_REFUSED);
    /*
     * This is the duplicate-message killer code.
     *
     * When mail delivered to a multidrop mailbox on the server is
     * addressed to multiple people on the client machine, there will
     * be one copy left in the box for each recipient.  This is not a
     * problem if we have the actual recipient address to dispatch on
     * (e.g. because we've mined it out of sendmail trace headers, or
     * a qmail Delivered-To line, or a declared sender envelope line).
     *
     * But if we're mining addressees out of the To/Cc/Bcc fields, and
     * if the mail is addressed to N people, each recipient will
     * get N copies.  This is bad when N > 1.
     *
     * Foil this by suppressing all but one copy of a message with a
     * given set of headers.
     *
     * Note: This implementation only catches runs of successive
     * messages with the same ID, but that should be good
     * enough. A more general implementation would have to store
     * ever-growing lists of seen message-IDs; in a long-running
     * daemon this would turn into a memory leak even if the 
     * implementation were perfect.
     * 
     * Don't mess with this code casually.  It would be way too easy
     * to break it in a way that blackholed mail.  Better to pass
     * the occasional duplicate than to do that...
     *
     * Matthias Andree:
     * The real fix however is to insist on Delivered-To: or similar
     * headers and require that one copy per recipient be dropped.
     * Everything else breaks sooner or later.
     */
    if (MULTIDROP(ctl) && msgblk.headers)
    {
	MD5_CTX context;

	MD5Init(&context);
	MD5Update(&context, (unsigned char *)msgblk.headers, strlen(msgblk.headers));
	MD5Final(ctl->digest, &context);

	if (!received_for && env_offs == -1 && !delivered_to)
	{
	    /*
	     * Hmmm...can MD5 ever yield all zeroes as a hash value?
	     * If so there is a one in 18-quadrillion chance this 
	     * code will incorrectly nuke the first message.
	     */
	    if (!memcmp(ctl->lastdigest, ctl->digest, DIGESTLEN))
		return(PS_REFUSED);
	}
	memcpy(ctl->lastdigest, ctl->digest, DIGESTLEN);
    }

    /*
     * Hack time.  If the first line of the message was blank, with no headers
     * (this happens occasionally due to bad gatewaying software) cons up
     * a set of fake headers.  
     *
     * If you modify the fake header template below, be sure you don't
     * make either From or To address @-less, otherwise the reply_hack
     * logic will do bad things.
     */
    if (msgblk.headers == (char *)NULL)
    {
	snprintf(buf, sizeof(buf),
		"From: FETCHMAIL-DAEMON\r\n"
		"To: %s@%s\r\n"
		"Subject: Headerless mail from %s's mailbox on %s\r\n",
		user, fetchmailhost, ctl->remotename, ctl->server.truename);
	msgblk.headers = xstrdup(buf);
    }

    /*
     * We can now process message headers before reading the text.
     * In fact we have to, as this will tell us where to forward to.
     */

    /* Check for MIME headers indicating possible 8-bit data */
    ctl->mimemsg = MimeBodyType(msgblk.headers, ctl->mimedecode);

#ifdef SDPS_ENABLE
    if (ctl->server.sdps && sdps_envfrom)
    {
	/* We have the real envelope return-path, stored out of band by
	 * SDPS - that's more accurate than any header is going to be.
	 */
	strlcpy(msgblk.return_path, sdps_envfrom, sizeof(msgblk.return_path));
	free(sdps_envfrom);
    } else
#endif /* SDPS_ENABLE */
    /*
     * If there is a Return-Path address on the message, this was
     * almost certainly the MAIL FROM address given the originating
     * sendmail.  This is the best thing to use for logging the
     * message origin (it sets up the right behavior for bounces and
     * mailing lists).  Otherwise, fall down to the next available 
     * envelope address (which is the most probable real sender).
     * *** The order is important! ***
     * This is especially useful when receiving mailing list
     * messages in multidrop mode.  if a local address doesn't
     * exist, the bounce message won't be returned blindly to the 
     * author or to the list itself but rather to the list manager
     * (ex: specified by "Sender:") which is much less annoying.  This 
     * is true for most mailing list packages.
     */
    if( !msgblk.return_path[0] ){
	char *ap = NULL;
	if (resent_sender_offs >= 0 && (ap = nxtaddr(msgblk.headers + resent_sender_offs)));
	else if (sender_offs >= 0 && (ap = nxtaddr(msgblk.headers + sender_offs)));
	else if (resent_from_offs >= 0 && (ap = nxtaddr(msgblk.headers + resent_from_offs)));
	else if (from_offs >= 0 && (ap = nxtaddr(msgblk.headers + from_offs)));
	else if (reply_to_offs >= 0 && (ap = nxtaddr(msgblk.headers + reply_to_offs)));
	else if (app_from_offs >= 0 && (ap = nxtaddr(msgblk.headers + app_from_offs))) {}
	/* multi-line MAIL FROM addresses confuse SMTP terribly */
	if (ap && !strchr(ap, '\n')) {
	    strncpy(msgblk.return_path, ap, sizeof(msgblk.return_path));
	    msgblk.return_path[sizeof(msgblk.return_path)-1] = '\0';
	}
    }

    /* cons up a list of local recipients */
    msgblk.recipients = (struct idlist *)NULL;
    accept_count = reject_count = 0;
    /* is this a multidrop box? */
    if (MULTIDROP(ctl))
    {
#ifdef SDPS_ENABLE
	if (ctl->server.sdps && sdps_envto)
	{
	    /* We have the real envelope recipient, stored out of band by
	     * SDPS - that's more accurate than any header is going to be.
	     */
	    find_server_names(sdps_envto, ctl, &msgblk.recipients);
	    free(sdps_envto);
	} else
#endif /* SDPS_ENABLE */ 
	if (env_offs > -1)	    /* We have the actual envelope addressee */
	    find_server_names(msgblk.headers + env_offs, ctl, &msgblk.recipients);
	else if (delivered_to && ctl->server.envelope != STRING_DISABLED &&
      ctl->server.envelope && !strcasecmp(ctl->server.envelope, "Delivered-To"))
   {
	    find_server_names(delivered_to, ctl, &msgblk.recipients);
	    xfree(delivered_to);
   }
	else if (received_for)
	    /*
	     * We have the Received for addressee.  
	     * It has to be a mailserver address, or we
	     * wouldn't have got here.
	     * We use find_server_names() to let local 
	     * hostnames go through.
	     */
	    find_server_names(received_for, ctl, &msgblk.recipients);
	else
	{
	    /*
	     * We haven't extracted the envelope address.
	     * So check all the "Resent-To" header addresses if 
	     * they exist.  If and only if they don't, consider
	     * the "To" addresses.
	     */
	    register struct addrblk *nextptr;
	    if (resent_to_addrchain) {
		/* delete the "To" chain and substitute it 
		 * with the "Resent-To" list 
		 */
		while (to_addrchain) {
		    nextptr = to_addrchain->next;
		    free(to_addrchain);
		    to_addrchain = nextptr;
		}
		to_addrchain = resent_to_addrchain;
		resent_to_addrchain = NULL;
	    }
	    /* now look for remaining adresses */
	    while (to_addrchain) {
		find_server_names(msgblk.headers+to_addrchain->offset, ctl, &msgblk.recipients);
		nextptr = to_addrchain->next;
		free(to_addrchain);
		to_addrchain = nextptr;
	    }
	}
	if (!accept_count)
	{
	    no_local_matches = TRUE;
	    save_str(&msgblk.recipients, run.postmaster, XMIT_ACCEPT);
	    if (outlevel >= O_DEBUG)
		report(stdout,
		      GT_("no local matches, forwarding to %s\n"),
		      run.postmaster);
	}
    }
    else	/* it's a single-drop box, use first localname */
	save_str(&msgblk.recipients, ctl->localnames->id, XMIT_ACCEPT);


    /*
     * Time to either address the message or decide we can't deliver it yet.
     */
    if (ctl->errcount > olderrs)	/* there were DNS errors above */
    {
	if (outlevel >= O_DEBUG)
	    report(stdout,
		   GT_("forwarding and deletion suppressed due to DNS errors\n"));
	return(PS_TRANSIENT);
    }
    else
    {
	/* set up stuffline() so we can deliver the message body through it */ 
	if ((n = open_sink(ctl, &msgblk,
			   &good_addresses, &bad_addresses)) != PS_SUCCESS)
	{
	    return(n);
	}
    }

    n = 0;
    /*
     * Some server/sendmail combinations cause problems when our
     * synthetic Received line is before the From header.  Cope
     * with this...
     */
    if ((rcv = strstr(msgblk.headers, "Received:")) == (char *)NULL)
	rcv = msgblk.headers;
    /* handle ">Received:" lines too */
    while (rcv > msgblk.headers && rcv[-1] != '\n')
	rcv--;
    if (rcv > msgblk.headers)
    {
	char	c = *rcv;

	*rcv = '\0';
	n = stuffline(ctl, msgblk.headers);
	*rcv = c;
    }
    if (!run.invisible && n != -1)
    {
	/* utter any per-message Received information we need here */
        if (ctl->server.trueaddr) {
	    char saddr[50];
	    int e;

	    e = getnameinfo(ctl->server.trueaddr, ctl->server.trueaddr_len,
		    saddr, sizeof(saddr), NULL, 0,
		    NI_NUMERICHOST);
	    if (e)
		snprintf(saddr, sizeof(saddr), "(%-.*s)", (int)(sizeof(saddr) - 3), gai_strerror(e));
	    snprintf(buf, sizeof(buf),
		    "Received: from %s [%s]\r\n", 
		    ctl->server.truename, saddr);
	} else {
	    snprintf(buf, sizeof(buf),
		  "Received: from %s\r\n", ctl->server.truename);
	}
	n = stuffline(ctl, buf);
	if (n != -1)
	{
	    /*
	     * We SHOULD (RFC-2821 sec. 4.4/p. 53) make sure to only use
	     * IANA registered protocol names here.
	     */
	    snprintf(buf, sizeof(buf),
		    "\tby %s with %s (fetchmail-%s",
		    fetchmailhost,
		    protocol->name,
		    VERSION);
	    if (ctl->server.tracepolls)
	    {
		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
			" polling %s account %s",
			ctl->server.pollname,
			ctl->remotename);
		if (ctl->folder)
		    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
			    " folder %s",
			    ctl->folder);
	    }
	    snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), ")\r\n");
	    n = stuffline(ctl, buf);
	    if (n != -1)
	    {
		buf[0] = '\t';
		if (good_addresses == 0)
		{
		    snprintf(buf+1, sizeof(buf)-1, "for <%s> (by default); ",
			    rcpt_address (ctl, run.postmaster, 0));
		}
		else if (good_addresses == 1)
		{
		    for (idp = msgblk.recipients; idp; idp = idp->next)
			if (idp->val.status.mark == XMIT_ACCEPT)
			    break;	/* only report first address */
		    if (idp)
			snprintf(buf+1, sizeof(buf)-1,
				"for <%s>", rcpt_address (ctl, idp->id, 1));
		    snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf)-1,
			    " (%s); ",
			    MULTIDROP(ctl) ? "multi-drop" : "single-drop");
		}
		else
		    buf[1] = '\0';

		snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s\r\n",
			rfc822timestamp());
		n = stuffline(ctl, buf);
	    }
	}
    }

    if (n != -1)
	n = stuffline(ctl, rcv);	/* ship out rest of msgblk.headers */

    if (n == -1)
    {
	report(stdout, GT_("writing RFC822 msgblk.headers\n"));
	release_sink(ctl);
	return(PS_IOERR);
    }
    
    if (want_progress())
	fputc('#', stdout);

    /* write error notifications */
    if (no_local_matches || has_nuls || bad_addresses)
    {
	int	errlen = 0;
	char	errhd[USERNAMELEN + POPBUFSIZE], *errmsg;

	errmsg = errhd;
	strlcpy(errhd, "X-Fetchmail-Warning: ", sizeof(errhd));
	if (no_local_matches)
	{
	    if (reject_count != 1)
		strlcat(errhd, GT_("no recipient addresses matched declared local names"), sizeof(errhd));
	    else
	    {
		for (idp = msgblk.recipients; idp; idp = idp->next)
		    if (idp->val.status.mark == XMIT_REJECT)
			break;
		snprintf(errhd+strlen(errhd), sizeof(errhd)-strlen(errhd),
			GT_("recipient address %s didn't match any local name"), idp->id);
	    }
	}

	if (has_nuls)
	{
	    if (errhd[sizeof("X-Fetchmail-Warning: ")])
		snprintf(errhd+strlen(errhd), sizeof(errhd)-strlen(errhd), "; ");
	    snprintf(errhd+strlen(errhd), sizeof(errhd)-strlen(errhd),
			GT_("message has embedded NULs"));
	}

	if (bad_addresses)
	{
	    if (errhd[sizeof("X-Fetchmail-Warning: ")])
		snprintf(errhd+strlen(errhd), sizeof(errhd)-strlen(errhd), "; ");
	    snprintf(errhd+strlen(errhd), sizeof(errhd)-strlen(errhd),
			GT_("SMTP listener rejected local recipient addresses: "));
	    errlen = strlen(errhd);
	    for (idp = msgblk.recipients; idp; idp = idp->next)
		if (idp->val.status.mark == XMIT_RCPTBAD)
		    errlen += strlen(idp->id) + 2;

	    errmsg = (char *)xmalloc(errlen + 3);
	    strcpy(errmsg, errhd);
	    for (idp = msgblk.recipients; idp; idp = idp->next)
		if (idp->val.status.mark == XMIT_RCPTBAD)
		{
		    strcat(errmsg, idp->id);
		    if (idp->next)
			strcat(errmsg, ", ");
		}

	}

	strcat(errmsg, "\r\n");

	/* ship out the error line */
	stuffline(ctl, errmsg);

	if (errmsg != errhd)
	    free(errmsg);
    }

    /* issue the delimiter line */
    cp = buf;
    *cp++ = '\r';
    *cp++ = '\n';
    *cp = '\0';
    n = stuffline(ctl, buf);

    if ((size_t)n == strlen(buf))
	return PS_SUCCESS;
    else
	return PS_SOCKET;
}
예제 #27
0
        hd->drivers &&
        search_str_list(hd_data->scanner_db, hd->drivers->str)
      ) {
        hd->base_class.id = bc_scanner;
      }

      // ###### FIXME
      if(hd->base_class.id == bc_modem) {
        hd->unix_dev_name = new_str("/dev/ttyACM0");
      }
    }

    sf_dev = free_mem(sf_dev);
  }

  sf_bus = free_str_list(sf_bus);

  /* connect usb devices to each other */
  for(hd = hd_data->hd; hd; hd = hd->next) {
    if(hd->module == hd_data->module && hd->sysfs_id) {

      s = new_str(hd->sysfs_id);
      t = strrchr(s, '/');
      if(t) *t = 0;

      /* parent has longest matching sysfs id */
      u2 = strlen(s);
      for(u3 = 0, hd1 = hd_data->hd; hd1; hd1 = hd1->next) {
        if(hd1->sysfs_id) {
          s1 = new_str(hd1->sysfs_id);
예제 #28
0
void hd_scan_net(hd_data_t *hd_data)
{
  unsigned u;
  int if_type, if_carrier;
  hd_t *hd, *hd_card;
  char *s, *t, *hw_addr;
  hd_res_t *res, *res1, *res2;
  uint64_t ul0;
  str_list_t *sf_class, *sf_class_e;
  char *sf_cdev = NULL, *sf_dev = NULL;
  char *sf_drv_name, *sf_drv;

  if(!hd_probe_feature(hd_data, pr_net)) return;

  hd_data->module = mod_net;

  /* some clean-up */
  remove_hd_entries(hd_data);
  hd_data->net = free_str_list(hd_data->net);

  PROGRESS(1, 0, "get network data");

  sf_class = read_dir("/sys/class/net", 'l');
  if(!sf_class) sf_class = read_dir("/sys/class/net", 'd');

  if(!sf_class) {
    ADD2LOG("sysfs: no such class: net\n");
    return;
  }

  for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) {
    str_printf(&sf_cdev, 0, "/sys/class/net/%s", sf_class_e->str);

    hd_card = NULL;

    ADD2LOG(
      "  net interface: name = %s, path = %s\n",
      sf_class_e->str,
      hd_sysfs_id(sf_cdev)
    );

    if_type = -1;
    if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "type"), &ul0, 0)) {
      if_type = ul0;
      ADD2LOG("    type = %d\n", if_type);
    }

    if_carrier = -1;
    if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "carrier"), &ul0, 0)) {
      if_carrier = ul0;
      ADD2LOG("    carrier = %d\n", if_carrier);
    }

    hw_addr = NULL;
    if((s = get_sysfs_attr_by_path(sf_cdev, "address"))) {
      hw_addr = canon_str(s, strlen(s));
      ADD2LOG("    hw_addr = %s\n", hw_addr);
    }

    sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device"));
    if(sf_dev) {
      ADD2LOG("    net device: path = %s\n", hd_sysfs_id(sf_dev));
    }

    sf_drv_name = NULL;
    sf_drv = hd_read_sysfs_link(sf_dev, "driver");
    if(sf_drv) {
      sf_drv_name = strrchr(sf_drv, '/');
      if(sf_drv_name) sf_drv_name++;
      ADD2LOG(
        "    net driver: name = %s, path = %s\n",
        sf_drv_name,
        hd_sysfs_id(sf_drv)
      );
    }

    hd = add_hd_entry(hd_data, __LINE__, 0);
    hd->base_class.id = bc_network_interface;
    hd->sub_class.id = sc_nif_other;

    res1 = NULL;
    if(hw_addr && strspn(hw_addr, "0:") != strlen(hw_addr)) {
      res1 = new_mem(sizeof *res1);
      res1->hwaddr.type = res_hwaddr;
      res1->hwaddr.addr = new_str(hw_addr);
      add_res_entry(&hd->res, res1);
    }

    res2 = NULL;
    if(if_carrier >= 0) {
      res = new_mem(sizeof *res);
      res->link.type = res_link;
      res->link.state = if_carrier ? 1 : 0;
      add_res_entry(&hd->res, res);
    }

    hd->unix_dev_name = new_str(sf_class_e->str);
    hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev));

    if(sf_drv_name) {
      add_str_list(&hd->drivers, sf_drv_name);
    }
    else if(hd->res) {
      get_driverinfo(hd_data, hd);
    }

    switch(if_type) {
      case ARPHRD_ETHER:	/* eth */
        hd->sub_class.id = sc_nif_ethernet;
        break;
      case ARPHRD_LOOPBACK:	/* lo */
        hd->sub_class.id = sc_nif_loopback;
        break;
      case ARPHRD_SIT:		/* sit */
        hd->sub_class.id = sc_nif_sit;
        break;
      case ARPHRD_FDDI:		/* fddi */
        hd->sub_class.id = sc_nif_fddi;
        break;
      case ARPHRD_IEEE802_TR:	/* tr */
        hd->sub_class.id = sc_nif_tokenring;
        break;
#if 0
      case ARPHRD_IEEE802:	/* fc */
        hd->sub_class.id = sc_nif_fc;
        break;
#endif
      default:
        hd->sub_class.id = sc_nif_other;
    }

    if(!strcmp(hd->unix_dev_name, "lo")) {
      hd->sub_class.id = sc_nif_loopback;
    }
    else if(sscanf(hd->unix_dev_name, "eth%u", &u) == 1) {
      hd->sub_class.id = sc_nif_ethernet;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "tr%u", &u) == 1) {
      hd->sub_class.id = sc_nif_tokenring;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "fddi%u", &u) == 1) {
      hd->sub_class.id = sc_nif_fddi;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "ctc%u", &u) == 1) {
      hd->sub_class.id = sc_nif_ctc;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "iucv%u", &u) == 1) {
      hd->sub_class.id = sc_nif_iucv;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "hsi%u", &u) == 1) {
      hd->sub_class.id = sc_nif_hsi;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "qeth%u", &u) == 1) {
      hd->sub_class.id = sc_nif_qeth;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "escon%u", &u) == 1) {
      hd->sub_class.id = sc_nif_escon;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "myri%u", &u) == 1) {
      hd->sub_class.id = sc_nif_myrinet;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "sit%u", &u) == 1) {
      hd->sub_class.id = sc_nif_sit;	/* ipv6 over ipv4 tunnel */
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "wlan%u", &u) == 1) {
      hd->sub_class.id = sc_nif_wlan;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "xp%u", &u) == 1) {
      hd->sub_class.id = sc_nif_xp;
      hd->slot = u;
    }
    else if(sscanf(hd->unix_dev_name, "usb%u", &u) == 1) {
      hd->sub_class.id = sc_nif_usb;
      hd->slot = u;
    }
    /* ##### add more interface names here */
    else {
      for(s = hd->unix_dev_name; *s; s++) if(isdigit(*s)) break;
      if(*s && (u = strtoul(s, &s, 10), !*s)) {
        hd->slot = u;
      }
    }

    hd->bus.id = bus_none;

    hd_card = NULL;

    if(sf_dev) {
      s = new_str(hd_sysfs_id(sf_dev));

      hd->sysfs_device_link = new_str(s);

      hd_card = hd_find_sysfs_id(hd_data, s);

      // try one above, if not found
      if(!hd_card) {
        t = strrchr(s, '/');
        if(t) {
          *t = 0;
          hd_card = hd_find_sysfs_id(hd_data, s);
        }
      }

      /* if one card has several interfaces (as with PS3), check interface names, too */
      if(
        hd_card &&
        hd_card->unix_dev_name &&
        hd->unix_dev_name &&
        strcmp(hd->unix_dev_name, hd_card->unix_dev_name)
      ) {
        hd_card = hd_find_sysfs_id_devname(hd_data, s, hd->unix_dev_name);
      }

      s = free_mem(s);

      if(hd_card) {
        hd->attached_to = hd_card->idx;

        /* for cards with strange pci classes */
        hd_set_hw_class(hd_card, hw_network_ctrl);

        /* add hw addr to network card */
        if(res1) {
          u = 0;
          for(res = hd_card->res; res; res = res->next) {
            if(
              res->any.type == res_hwaddr &&
              !strcmp(res->hwaddr.addr, res1->hwaddr.addr)
            ) {
              u = 1;
              break;
            }
          }
          if(!u) {
            res = new_mem(sizeof *res);
            res->hwaddr.type = res_hwaddr;
            res->hwaddr.addr = new_str(res1->hwaddr.addr);
            add_res_entry(&hd_card->res, res);
          }
        }
        /*
         * add interface names...
         * but not wmasterX (bnc #441778)
         */
        if(if_type != 801) add_if_name(hd_card, hd);
      }
    }

    if(!hd_card && hw_addr) {
      /* try to find card based on hwaddr (for prom-based cards) */

      for(hd_card = hd_data->hd; hd_card; hd_card = hd_card->next) {
        if(
          hd_card->base_class.id != bc_network ||
          hd_card->sub_class.id != 0
        ) continue;
        for(res = hd_card->res; res; res = res->next) {
          if(
            res->any.type == res_hwaddr &&
            !strcmp(hw_addr, res->hwaddr.addr)
          ) break;
        }
        if(res) {
          hd->attached_to = hd_card->idx;
          break;
        }
      }
    }

    hw_addr = free_mem(hw_addr);

    /* fix card type */
    if(hd_card) {
      if(
        (hd_card->base_class.id == 0 && hd_card->sub_class.id == 0) ||
        (hd_card->base_class.id == bc_network && hd_card->sub_class.id == 0x80)
      ) {
        switch(hd->sub_class.id) {
          case sc_nif_ethernet:
            hd_card->base_class.id = bc_network;
            hd_card->sub_class.id = 0;
            break;

          case sc_nif_usb:
            hd_card->base_class.id = bc_network;
            hd_card->sub_class.id = 0x91;
            break;
        }
      }
    }

    sf_dev = free_mem(sf_dev);
  }

  sf_cdev = free_mem(sf_cdev);
  sf_class = free_str_list(sf_class);

  if(hd_is_sgi_altix(hd_data)) add_xpnet(hd_data);
  add_uml(hd_data);
  add_kma(hd_data);

  /* add link status info & dump eeprom */
  for(hd = hd_data->hd ; hd; hd = hd->next) {
    if(
      hd->module == hd_data->module &&
      hd->base_class.id == bc_network_interface
    ) {
      char *buf = NULL;
      str_list_t *sl0, *sl;

      if(hd_probe_feature(hd_data, pr_net_eeprom) && hd->unix_dev_name) {
        PROGRESS(2, 0, "eeprom dump");

        str_printf(&buf, 0, "|/usr/sbin/ethtool -e %s 2>/dev/null", hd->unix_dev_name);
        if((sl0 = read_file(buf, 0, 0))) {
          ADD2LOG("----- %s %s -----\n", hd->unix_dev_name, "EEPROM dump");
          for(sl = sl0; sl; sl = sl->next) {
            ADD2LOG("%s", sl->str);
          }
          ADD2LOG("----- %s end -----\n", "EEPROM dump");
          free_str_list(sl0);
        }
        free(buf);
      }

      for(res = hd->res; res; res = res->next) {
        if(res->any.type == res_link) break;
      }

      if(!res) get_linkstate(hd_data, hd);

      if(!(hd_card = hd_get_device_by_idx(hd_data, hd->attached_to))) continue;

      for(res = hd->res; res; res = res->next) {
        if(res->any.type == res_link) break;
      }

      if(res) {
        for(res1 = hd_card->res; res1; res1 = res1->next) {
          if(res1->any.type == res_link) break;
        }
        if(res && !res1) {
          res1 = new_mem(sizeof *res1);
          res1->link.type = res_link;
          res1->link.state = res->link.state;
          add_res_entry(&hd_card->res, res1);
        }
      }
    }
  }
}
예제 #29
0
파일: x11gui.c 프로젝트: htrb/ngraph-gtk
static void
fsok(GtkWidget *dlg)
{
  struct nGetOpenFileData *data;
  char *file, *file2, **farray;
  const char *filter_name;
  int i, k, len, n;
  GStatBuf buf;
  GSList *top, *list;
  GtkFileFilter *filter;

  data = &FileSelection;

  top = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dlg));
  filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dlg));

  if (filter) {
    filter_name = gtk_file_filter_get_name(filter);
  } else {
    filter_name = NULL;
  }

  if (filter_name == NULL || strcmp(filter_name, _("All")) == 0) {
    data->ext = NULL;
  }

  n = g_slist_length(top);
  farray = g_malloc(sizeof(*farray) * (n + 1));
  if (farray == NULL) {
    free_str_list(top);
    return;
  }
  data->file = farray;

  k = 0;
  for (list = top; list; list = list->next) {
    char *tmp;

    tmp = (char *) list->data;
    if (tmp == NULL || strlen(tmp) < 1) {
      gdk_beep();
      continue;
    }

    file = get_utf8_filename(tmp);

    for (i = strlen(file) - 1; (i > 0) && (file[i] != '/') && (file[i] != '.'); i--);
    if ((file[i] != '.') && data->ext) {
      len = strlen(data->ext) + 1;
    } else {
      len = 0;
    }

    if (len) {
      file2 = g_strdup_printf("%s.%s", file, data->ext);
      g_free(file);
    } else {
      file2 = file;
    }
    if (file2) {
      if (data->mustexist) {
	if ((nstat(file2, &buf) != 0) || ((buf.st_mode & S_IFMT) != S_IFREG)
	    || (naccess(file2, R_OK) != 0)) {
	  gdk_beep();
	  error22(NULL, 0, "I/O error", file2);
	  g_free(file2);
	  continue;
	}
      } else {
	if ((nstat(file2, &buf) == 0) && ((buf.st_mode & S_IFMT) != S_IFREG)) {
	  gdk_beep();
	  error22(NULL, 0, "I/O error", file2);
	  g_free(file2);
	  continue;
	}
      }
      farray[k] = file2;
      k++;
    }
  }

  if (k == 0)
    return;

  if (data->changedir && k > 0) {
    data->chdir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->chdir_cb));
    if (data->chdir && data->init_dir) {
      char *dir;

      g_free(*(data->init_dir));
      dir = g_path_get_dirname(farray[0]);
      *(data->init_dir) = dir;
    }
  }
  farray[k] = NULL;
  free_str_list(top);
  data->ret = IDOK;
}
예제 #30
0
void _send_list(aClient *cptr, int numsend)
{
	aChannel *chptr;
	LOpts *lopt = cptr->user->lopt;
	unsigned int  hashnum;

	/* Begin of /list? then send official channels. */
	if ((lopt->starthash == 0) && conf_offchans)
	{
		ConfigItem_offchans *x;
		for (x = conf_offchans; x; x = (ConfigItem_offchans *)x->next)
		{
			if (find_channel(x->chname, (aChannel *)NULL))
				continue; /* exists, >0 users.. will be sent later */
			sendto_one(cptr,
			    rpl_str(RPL_LIST), me.name,
			    cptr->name, x->chname,
			    0,
#ifdef LIST_SHOW_MODES
			    "",
#endif					    
			    x->topic ? x->topic : "");
		}
	}

	for (hashnum = lopt->starthash; hashnum < CH_MAX; hashnum++)
	{
		if (numsend > 0)
			for (chptr =
			    (aChannel *)hash_get_chan_bucket(hashnum);
			    chptr; chptr = chptr->hnextch)
			{
				if (SecretChannel(chptr)
				    && !IsMember(cptr, chptr)
				    && !OPCanSeeSecret(cptr))
					continue;

				/* Much more readable like this -- codemastr */
				if ((!lopt->showall))
				{
					/* User count must be in range */
					if ((chptr->users < lopt->usermin) || 
					    ((lopt->usermax >= 0) && (chptr->users > 
					    lopt->usermax)))
						continue;

					/* Creation time must be in range */
					if ((chptr->creationtime && (chptr->creationtime <
					    lopt->chantimemin)) || (chptr->creationtime >
					    lopt->chantimemax))
						continue;

					/* Topic time must be in range */
					if ((chptr->topic_time < lopt->topictimemin) ||
					    (chptr->topic_time > lopt->topictimemax))
						continue;

					/* Must not be on nolist (if it exists) */
					if (lopt->nolist && find_str_match_link(lopt->nolist,
					    chptr->chname))
						continue;

					/* Must be on yeslist (if it exists) */
					if (lopt->yeslist && !find_str_match_link(lopt->yeslist,
					    chptr->chname))
						continue;
				}
#ifdef LIST_SHOW_MODES
				modebuf[0] = '[';
				channel_modes(cptr, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), chptr);
				if (modebuf[2] == '\0')
					modebuf[0] = '\0';
				else
					strlcat(modebuf, "]", sizeof modebuf);
#endif
				if (!OPCanSeeSecret(cptr))
					sendto_one(cptr,
					    rpl_str(RPL_LIST), me.name,
					    cptr->name,
					    ShowChannel(cptr,
					    chptr) ? chptr->chname :
					    "*", chptr->users,
#ifdef LIST_SHOW_MODES
					    ShowChannel(cptr, chptr) ?
					    modebuf : "",
#endif
					    ShowChannel(cptr,
					    chptr) ? (chptr->topic ?
					    chptr->topic : "") : "");
				else
					sendto_one(cptr,
					    rpl_str(RPL_LIST), me.name,
					    cptr->name, chptr->chname,
					    chptr->users,
#ifdef LIST_SHOW_MODES
					    modebuf,
#endif					    
					    (chptr->topic ? chptr->topic : ""));
				numsend--;
			}
		else
			break;
	}

	/* All done */
	if (hashnum == CH_MAX)
	{
		sendto_one(cptr, rpl_str(RPL_LISTEND), me.name, cptr->name);
		free_str_list(cptr->user->lopt->yeslist);
		free_str_list(cptr->user->lopt->nolist);
		MyFree(cptr->user->lopt);
		cptr->user->lopt = NULL;
		return;
	}

	/* 
	 * We've exceeded the limit on the number of channels to send back
	 * at once.
	 */
	lopt->starthash = hashnum;
	return;
}